xref: /DragonOS/kernel/crates/rbpf/tests/cranelift.rs (revision 55e6f0b65f91b32638fd56581f711a816eccdcd1)
1 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
2 
3 #![allow(clippy::unreadable_literal)]
4 #![cfg(feature = "cranelift")]
5 
6 extern crate rbpf;
7 mod common;
8 
9 use rbpf::{assembler::assemble, helpers};
10 
11 use crate::common::{TCP_SACK_ASM, TCP_SACK_MATCH, TCP_SACK_NOMATCH};
12 
13 macro_rules! test_cranelift {
14     ($name:ident, $prog:expr, $expected:expr) => {
15         #[test]
16         fn $name() {
17             let prog = assemble($prog).unwrap();
18             let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
19             vm.cranelift_compile().unwrap();
20             assert_eq!(vm.execute_program_cranelift().unwrap(), $expected);
21         }
22     };
23     ($name:ident, $prog:expr, $mem:expr, $expected:expr) => {
24         #[test]
25         fn $name() {
26             let prog = assemble($prog).unwrap();
27             let mem = &mut $mem;
28             let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
29             vm.cranelift_compile().unwrap();
30             assert_eq!(vm.execute_program_cranelift(mem).unwrap(), $expected);
31         }
32     };
33 }
34 
35 test_cranelift!(
36     test_cranelift_add,
37     "
38     mov32 r0, 0
39     mov32 r1, 2
40     add32 r0, 1
41     add32 r0, r1
42     exit
43     ",
44     0x3
45 );
46 
47 test_cranelift!(
48     test_cranelift_alu64_arith,
49     "
50     mov r0, 0
51     mov r1, 1
52     mov r2, 2
53     mov r3, 3
54     mov r4, 4
55     mov r5, 5
56     mov r6, 6
57     mov r7, 7
58     mov r8, 8
59     mov r9, 9
60     add r0, 23
61     add r0, r7
62     sub r0, 13
63     sub r0, r1
64     mul r0, 7
65     mul r0, r3
66     div r0, 2
67     div r0, r4
68     exit
69     ",
70     0x2a
71 );
72 
73 test_cranelift!(
74     test_cranelift_alu64_bit,
75     "
76     mov r0, 0
77     mov r1, 1
78     mov r2, 2
79     mov r3, 3
80     mov r4, 4
81     mov r5, 5
82     mov r6, 6
83     mov r7, 7
84     mov r8, 8
85     or r0, r5
86     or r0, 0xa0
87     and r0, 0xa3
88     mov r9, 0x91
89     and r0, r9
90     lsh r0, 32
91     lsh r0, 22
92     lsh r0, r8
93     rsh r0, 32
94     rsh r0, 19
95     rsh r0, r7
96     xor r0, 0x03
97     xor r0, r2
98     exit
99     ",
100     0x11
101 );
102 
103 test_cranelift!(
104     test_cranelift_alu_arith,
105     "
106     mov32 r0, 0
107     mov32 r1, 1
108     mov32 r2, 2
109     mov32 r3, 3
110     mov32 r4, 4
111     mov32 r5, 5
112     mov32 r6, 6
113     mov32 r7, 7
114     mov32 r8, 8
115     mov32 r9, 9
116     add32 r0, 23
117     add32 r0, r7
118     sub32 r0, 13
119     sub32 r0, r1
120     mul32 r0, 7
121     mul32 r0, r3
122     div32 r0, 2
123     div32 r0, r4
124     exit
125     ",
126     0x2a
127 );
128 
129 test_cranelift!(
130     test_cranelift_alu_bit,
131     "
132     mov32 r0, 0
133     mov32 r1, 1
134     mov32 r2, 2
135     mov32 r3, 3
136     mov32 r4, 4
137     mov32 r5, 5
138     mov32 r6, 6
139     mov32 r7, 7
140     mov32 r8, 8
141     or32 r0, r5
142     or32 r0, 0xa0
143     and32 r0, 0xa3
144     mov32 r9, 0x91
145     and32 r0, r9
146     lsh32 r0, 22
147     lsh32 r0, r8
148     rsh32 r0, 19
149     rsh32 r0, r7
150     xor32 r0, 0x03
151     xor32 r0, r2
152     exit
153     ",
154     0x11
155 );
156 
157 test_cranelift!(
158     test_cranelift_arsh32_high_shift,
159     "
160     mov r0, 8
161     lddw r1, 0x100000001
162     arsh32 r0, r1
163     exit
164     ",
165     0x4
166 );
167 
168 test_cranelift!(
169     test_cranelift_arsh,
170     "
171     mov32 r0, 0xf8
172     lsh32 r0, 28
173     arsh32 r0, 16
174     exit
175     ",
176     0xffff8000
177 );
178 
179 test_cranelift!(
180     test_cranelift_arsh64,
181     "
182     mov32 r0, 1
183     lsh r0, 63
184     arsh r0, 55
185     mov32 r1, 5
186     arsh r0, r1
187     exit
188     ",
189     0xfffffffffffffff8
190 );
191 
192 test_cranelift!(
193     test_cranelift_arsh_reg,
194     "
195     mov32 r0, 0xf8
196     mov32 r1, 16
197     lsh32 r0, 28
198     arsh32 r0, r1
199     exit
200     ",
201     0xffff8000
202 );
203 
204 test_cranelift!(
205     test_cranelift_be16,
206     "
207     ldxh r0, [r1]
208     be16 r0
209     exit
210     ",
211     [0x11, 0x22],
212     0x1122
213 );
214 
215 test_cranelift!(
216     test_cranelift_be16_high,
217     "
218     ldxdw r0, [r1]
219     be16 r0
220     exit
221     ",
222     [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
223     0x1122
224 );
225 
226 test_cranelift!(
227     test_cranelift_be32,
228     "
229     ldxw r0, [r1]
230     be32 r0
231     exit
232     ",
233     [0x11, 0x22, 0x33, 0x44],
234     0x11223344
235 );
236 
237 test_cranelift!(
238     test_cranelift_be32_high,
239     "
240     ldxdw r0, [r1]
241     be32 r0
242     exit
243     ",
244     [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
245     0x11223344
246 );
247 
248 test_cranelift!(
249     test_cranelift_be64,
250     "
251     ldxdw r0, [r1]
252     be64 r0
253     exit
254     ",
255     [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
256     0x1122334455667788
257 );
258 
259 #[test]
260 fn test_cranelift_call() {
261     let prog = assemble(
262         "
263         mov r1, 1
264         mov r2, 2
265         mov r3, 3
266         mov r4, 4
267         mov r5, 5
268         call 0
269         exit",
270     )
271     .unwrap();
272 
273     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
274     vm.register_helper(0, helpers::gather_bytes).unwrap();
275     vm.cranelift_compile().unwrap();
276     assert_eq!(vm.execute_program_cranelift().unwrap(), 0x0102030405);
277 }
278 
279 #[test]
280 #[should_panic(expected = "[CRANELIFT] Error: unknown helper function (id: 0x3f)")]
281 fn test_cranelift_err_call_unreg() {
282     let prog = assemble(
283         "
284          mov r1, 1
285          mov r2, 2
286          mov r3, 3
287          mov r4, 4
288          mov r5, 5
289          call 63
290          exit
291     ",
292     )
293     .unwrap();
294     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
295     vm.cranelift_compile().unwrap();
296 }
297 
298 #[test]
299 fn test_cranelift_call_memfrob() {
300     let prog = assemble(
301         "
302         mov r6, r1
303         add r1, 2
304         mov r2, 4
305         call 1
306         ldxdw r0, [r6]
307         be64 r0
308         exit",
309     )
310     .unwrap();
311 
312     let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
313     vm.register_helper(1, helpers::memfrob).unwrap();
314     let mem = &mut [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
315     vm.cranelift_compile().unwrap();
316     assert_eq!(
317         vm.execute_program_cranelift(mem).unwrap(),
318         0x102292e2f2c0708
319     );
320 }
321 
322 test_cranelift!(
323     test_cranelift_div32_high_divisor,
324     "
325     mov r0, 12
326     lddw r1, 0x100000004
327     div32 r0, r1
328     exit
329     ",
330     0x3
331 );
332 
333 test_cranelift!(
334     test_cranelift_div32_imm,
335     "
336     lddw r0, 0x10000000c
337     div32 r0, 4
338     exit
339     ",
340     0x3
341 );
342 
343 test_cranelift!(
344     test_cranelift_div32_reg,
345     "
346     lddw r0, 0x10000000c
347     mov r1, 4
348     div32 r0, r1
349     exit
350     ",
351     0x3
352 );
353 
354 test_cranelift!(
355     test_cranelift_div64_imm,
356     "
357     mov r0, 0xc
358     lsh r0, 32
359     div r0, 4
360     exit
361     ",
362     0x300000000
363 );
364 
365 test_cranelift!(
366     test_cranelift_div64_reg,
367     "
368     mov r0, 0xc
369     lsh r0, 32
370     mov r1, 4
371     div r0, r1
372     exit
373     ",
374     0x300000000
375 );
376 
377 test_cranelift!(
378     test_cranelift_early_exit,
379     "
380     mov r0, 3
381     exit
382     mov r0, 4
383     exit
384     ",
385     0x3
386 );
387 
388 test_cranelift!(
389     test_cranelift_div64_by_zero_imm,
390     "
391     mov32 r0, 1
392     div r0, 0
393     exit
394     ",
395     0x0
396 );
397 
398 test_cranelift!(
399     test_cranelift_div_by_zero_imm,
400     "
401     mov32 r0, 1
402     div32 r0, 0
403     exit
404     ",
405     0x0
406 );
407 
408 test_cranelift!(
409     test_cranelift_mod64_by_zero_imm,
410     "
411     mov32 r0, 1
412     mod r0, 0
413     exit
414     ",
415     0x1
416 );
417 
418 test_cranelift!(
419     test_cranelift_mod_by_zero_imm,
420     "
421     mov32 r0, 1
422     mod32 r0, 0
423     exit
424     ",
425     0x1
426 );
427 
428 test_cranelift!(
429     test_cranelift_div64_by_zero_reg,
430     "
431     mov32 r0, 1
432     mov32 r1, 0
433     div r0, r1
434     exit
435     ",
436     0x0
437 );
438 
439 test_cranelift!(
440     test_cranelift_div_by_zero_reg,
441     "
442     mov32 r0, 1
443     mov32 r1, 0
444     div32 r0, r1
445     exit
446     ",
447     0x0
448 );
449 
450 test_cranelift!(
451     test_cranelift_mod64_by_zero_reg,
452     "
453     mov32 r0, 1
454     mov32 r1, 0
455     mod r0, r1
456     exit
457     ",
458     0x1
459 );
460 
461 test_cranelift!(
462     test_cranelift_mod_by_zero_reg,
463     "
464     mov32 r0, 1
465     mov32 r1, 0
466     mod32 r0, r1
467     exit
468     ",
469     0x1
470 );
471 
472 #[test]
473 // #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
474 #[ignore = "We have stack OOB checks, but we don't yet catch the trap code and convert it into a panic"]
475 fn test_cranelift_err_stack_out_of_bound() {
476     let prog = [
477         0x72, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478         0x00,
479     ];
480     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
481     vm.cranelift_compile().unwrap();
482     vm.execute_program_cranelift().unwrap();
483 }
484 
485 test_cranelift!(
486     test_cranelift_exit,
487     "
488     mov r0, 0
489     exit
490     ",
491     0x0
492 );
493 
494 test_cranelift!(
495     test_cranelift_ja,
496     "
497     mov r0, 1
498     ja +1
499     mov r0, 2
500     exit
501     ",
502     0x1
503 );
504 
505 test_cranelift!(
506     test_cranelift_jeq_imm,
507     "
508     mov32 r0, 0
509     mov32 r1, 0xa
510     jeq r1, 0xb, +4
511     mov32 r0, 1
512     mov32 r1, 0xb
513     jeq r1, 0xb, +1
514     mov32 r0, 2
515     exit
516     ",
517     0x1
518 );
519 
520 test_cranelift!(
521     test_cranelift_jeq_reg,
522     "
523     mov32 r0, 0
524     mov32 r1, 0xa
525     mov32 r2, 0xb
526     jeq r1, r2, +4
527     mov32 r0, 1
528     mov32 r1, 0xb
529     jeq r1, r2, +1
530     mov32 r0, 2
531     exit
532     ",
533     0x1
534 );
535 
536 test_cranelift!(
537     test_cranelift_jge_imm,
538     "
539     mov32 r0, 0
540     mov32 r1, 0xa
541     jge r1, 0xb, +4
542     mov32 r0, 1
543     mov32 r1, 0xc
544     jge r1, 0xb, +1
545     mov32 r0, 2
546     exit
547     ",
548     0x1
549 );
550 
551 test_cranelift!(
552     test_cranelift_jle_imm,
553     "
554     mov32 r0, 0
555     mov32 r1, 5
556     jle r1, 4, +1
557     jle r1, 6, +1
558     exit
559     jle r1, 5, +1
560     exit
561     mov32 r0, 1
562     exit
563     ",
564     0x1
565 );
566 
567 test_cranelift!(
568     test_cranelift_jle_reg,
569     "
570     mov r0, 0
571     mov r1, 5
572     mov r2, 4
573     mov r3, 6
574     jle r1, r2, +2
575     jle r1, r1, +1
576     exit
577     jle r1, r3, +1
578     exit
579     mov r0, 1
580     exit
581     ",
582     0x1
583 );
584 
585 test_cranelift!(
586     test_cranelift_jgt_imm,
587     "
588     mov32 r0, 0
589     mov32 r1, 5
590     jgt r1, 6, +2
591     jgt r1, 5, +1
592     jgt r1, 4, +1
593     exit
594     mov32 r0, 1
595     exit
596     ",
597     0x1
598 );
599 
600 test_cranelift!(
601     test_cranelift_jgt_reg,
602     "
603     mov r0, 0
604     mov r1, 5
605     mov r2, 6
606     mov r3, 4
607     jgt r1, r2, +2
608     jgt r1, r1, +1
609     jgt r1, r3, +1
610     exit
611     mov r0, 1
612     exit
613     ",
614     0x1
615 );
616 
617 test_cranelift!(
618     test_cranelift_jlt_imm,
619     "
620     mov32 r0, 0
621     mov32 r1, 5
622     jlt r1, 4, +2
623     jlt r1, 5, +1
624     jlt r1, 6, +1
625     exit
626     mov32 r0, 1
627     exit
628     ",
629     0x1
630 );
631 
632 test_cranelift!(
633     test_cranelift_jlt_reg,
634     "
635     mov r0, 0
636     mov r1, 5
637     mov r2, 4
638     mov r3, 6
639     jlt r1, r2, +2
640     jlt r1, r1, +1
641     jlt r1, r3, +1
642     exit
643     mov r0, 1
644     exit
645     ",
646     0x1
647 );
648 
649 test_cranelift!(
650     test_cranelift_jit_bounce,
651     "
652     mov r0, 1
653     mov r6, r0
654     mov r7, r6
655     mov r8, r7
656     mov r9, r8
657     mov r0, r9
658     exit
659     ",
660     0x1
661 );
662 
663 test_cranelift!(
664     test_cranelift_jne_reg,
665     "
666     mov32 r0, 0
667     mov32 r1, 0xb
668     mov32 r2, 0xb
669     jne r1, r2, +4
670     mov32 r0, 1
671     mov32 r1, 0xa
672     jne r1, r2, +1
673     mov32 r0, 2
674     exit
675     ",
676     0x1
677 );
678 
679 test_cranelift!(
680     test_cranelift_jset_imm,
681     "
682     mov32 r0, 0
683     mov32 r1, 0x7
684     jset r1, 0x8, +4
685     mov32 r0, 1
686     mov32 r1, 0x9
687     jset r1, 0x8, +1
688     mov32 r0, 2
689     exit
690     ",
691     0x1
692 );
693 
694 test_cranelift!(
695     test_cranelift_jset_reg,
696     "
697     mov32 r0, 0
698     mov32 r1, 0x7
699     mov32 r2, 0x8
700     jset r1, r2, +4
701     mov32 r0, 1
702     mov32 r1, 0x9
703     jset r1, r2, +1
704     mov32 r0, 2
705     exit
706     ",
707     0x1
708 );
709 
710 test_cranelift!(
711     test_cranelift_jsge_imm,
712     "
713     mov32 r0, 0
714     mov r1, -2
715     jsge r1, -1, +5
716     jsge r1, 0, +4
717     mov32 r0, 1
718     mov r1, -1
719     jsge r1, -1, +1
720     mov32 r0, 2
721     exit
722     ",
723     0x1
724 );
725 
726 test_cranelift!(
727     test_cranelift_jsge_reg,
728     "
729     mov32 r0, 0
730     mov r1, -2
731     mov r2, -1
732     mov32 r3, 0
733     jsge r1, r2, +5
734     jsge r1, r3, +4
735     mov32 r0, 1
736     mov r1, r2
737     jsge r1, r2, +1
738     mov32 r0, 2
739     exit
740     ",
741     0x1
742 );
743 
744 test_cranelift!(
745     test_cranelift_jsle_imm,
746     "
747     mov32 r0, 0
748     mov r1, -2
749     jsle r1, -3, +1
750     jsle r1, -1, +1
751     exit
752     mov32 r0, 1
753     jsle r1, -2, +1
754     mov32 r0, 2
755     exit
756     ",
757     0x1
758 );
759 
760 test_cranelift!(
761     test_cranelift_jsle_reg,
762     "
763     mov32 r0, 0
764     mov r1, -1
765     mov r2, -2
766     mov32 r3, 0
767     jsle r1, r2, +1
768     jsle r1, r3, +1
769     exit
770     mov32 r0, 1
771     mov r1, r2
772     jsle r1, r2, +1
773     mov32 r0, 2
774     exit
775     ",
776     0x1
777 );
778 
779 test_cranelift!(
780     test_cranelift_jsgt_imm,
781     "
782     mov32 r0, 0
783     mov r1, -2
784     jsgt r1, -1, +4
785     mov32 r0, 1
786     mov32 r1, 0
787     jsgt r1, -1, +1
788     mov32 r0, 2
789     exit
790     ",
791     0x1
792 );
793 
794 test_cranelift!(
795     test_cranelift_jsgt_reg,
796     "
797     mov32 r0, 0
798     mov r1, -2
799     mov r2, -1
800     jsgt r1, r2, +4
801     mov32 r0, 1
802     mov32 r1, 0
803     jsgt r1, r2, +1
804     mov32 r0, 2
805     exit
806     ",
807     0x1
808 );
809 
810 test_cranelift!(
811     test_cranelift_jslt_imm,
812     "
813     mov32 r0, 0
814     mov r1, -2
815     jslt r1, -3, +2
816     jslt r1, -2, +1
817     jslt r1, -1, +1
818     exit
819     mov32 r0, 1
820     exit
821     ",
822     0x1
823 );
824 
825 test_cranelift!(
826     test_cranelift_jslt_reg,
827     "
828     mov32 r0, 0
829     mov r1, -2
830     mov r2, -3
831     mov r3, -1
832     jslt r1, r1, +2
833     jslt r1, r2, +1
834     jslt r1, r3, +1
835     exit
836     mov32 r0, 1
837     exit
838     ",
839     0x1
840 );
841 
842 test_cranelift!(
843     test_cranelift_jeq32_imm,
844     "
845     mov r9, 1
846     lsh r9, 32
847     mov32 r0, 0x0
848     mov32 r1, 0xa
849     jeq32 r1, 0xb, +5
850     mov32 r0, 1
851     mov r1, 0xb
852     or r1, r9
853     jeq32 r1, 0xb, +1
854     mov32 r0, 2
855     exit
856     ",
857     0x1
858 );
859 
860 test_cranelift!(
861     test_cranelift_jeq32_reg,
862     "
863     mov r9, 1
864     lsh r9, 32
865     mov32 r0, 0
866     mov32 r1, 0xa
867     mov32 r2, 0xb
868     jeq32 r1, r2, +5
869     mov32 r0, 1
870     mov32 r1, 0xb
871     or r1, r9
872     jeq32 r1, r2, +1
873     mov32 r0, 2
874     exit
875     ",
876     0x1
877 );
878 
879 test_cranelift!(
880     test_cranelift_jge32_imm,
881     "
882     mov r9, 1
883     lsh r9, 32
884     mov32 r0, 0
885     mov32 r1, 0xa
886     jge32 r1, 0xb, +5
887     mov32 r0, 1
888     or r1, r9
889     mov32 r1, 0xc
890     jge32 r1, 0xb, +1
891     mov32 r0, 2
892     exit
893     ",
894     0x1
895 );
896 
897 test_cranelift!(
898     test_cranelift_jge32_reg,
899     "
900     mov r9, 1
901     lsh r9, 32
902     mov32 r0, 0
903     mov32 r1, 0xa
904     mov32 r2, 0xb
905     jge32 r1, r2, +5
906     mov32 r0, 1
907     or r1, r9
908     mov32 r1, 0xc
909     jge32 r1, r2, +1
910     mov32 r0, 2
911     exit
912     ",
913     0x1
914 );
915 
916 test_cranelift!(
917     test_cranelift_jgt32_imm,
918     "
919     mov r9, 1
920     lsh r9, 32
921     mov32 r0, 0
922     mov32 r1, 5
923     or r1, r9
924     jgt32 r1, 6, +4
925     jgt32 r1, 5, +3
926     jgt32 r1, 4, +1
927     exit
928     mov32 r0, 1
929     exit
930     ",
931     0x1
932 );
933 
934 test_cranelift!(
935     test_cranelift_jgt32_reg,
936     "
937     mov r9, 1
938     lsh r9, 32
939     mov r0, 0
940     mov r1, 5
941     mov32 r1, 5
942     or r1, r9
943     mov r2, 6
944     mov r3, 4
945     jgt32 r1, r2, +4
946     jgt32 r1, r1, +3
947     jgt32 r1, r3, +1
948     exit
949     mov r0, 1
950     exit
951     ",
952     0x1
953 );
954 
955 test_cranelift!(
956     test_cranelift_jle32_imm,
957     "
958     mov r9, 1
959     lsh r9, 32
960     mov32 r0, 0
961     mov32 r1, 5
962     or r1, r9
963     jle32 r1, 4, +5
964     jle32 r1, 6, +1
965     exit
966     jle32 r1, 5, +1
967     exit
968     mov32 r0, 1
969     exit
970     ",
971     0x1
972 );
973 
974 test_cranelift!(
975     test_cranelift_jle32_reg,
976     "
977     mov r9, 1
978     lsh r9, 32
979     mov r0, 0
980     mov r1, 5
981     mov r2, 4
982     mov r3, 6
983     or r1, r9
984     jle32 r1, r2, +5
985     jle32 r1, r1, +1
986     exit
987     jle32 r1, r3, +1
988     exit
989     mov r0, 1
990     exit
991     ",
992     0x1
993 );
994 
995 test_cranelift!(
996     test_cranelift_jlt32_imm,
997     "
998     mov r9, 1
999     lsh r9, 32
1000     mov32 r0, 0
1001     mov32 r1, 5
1002     or r1, r9
1003     jlt32 r1, 4, +4
1004     jlt32 r1, 5, +3
1005     jlt32 r1, 6, +1
1006     exit
1007     mov32 r0, 1
1008     exit
1009     ",
1010     0x1
1011 );
1012 
1013 test_cranelift!(
1014     test_cranelift_jlt32_reg,
1015     "
1016     mov r9, 1
1017     lsh r9, 32
1018     mov r0, 0
1019     mov r1, 5
1020     mov r2, 4
1021     mov r3, 6
1022     or r1, r9
1023     jlt32 r1, r2, +4
1024     jlt32 r1, r1, +3
1025     jlt32 r1, r3, +1
1026     exit
1027     mov r0, 1
1028     exit
1029     ",
1030     0x1
1031 );
1032 
1033 test_cranelift!(
1034     test_cranelift_jne32_imm,
1035     "
1036     mov r9, 1
1037     lsh r9, 32
1038     mov32 r0, 0
1039     mov32 r1, 0xb
1040     or r1, r9
1041     jne32 r1, 0xb, +4
1042     mov32 r0, 1
1043     mov32 r1, 0xa
1044     or r1, r9
1045     jne32 r1, 0xb, +1
1046     mov32 r0, 2
1047     exit
1048     ",
1049     0x1
1050 );
1051 
1052 test_cranelift!(
1053     test_cranelift_jne32_reg,
1054     "
1055     mov r9, 1
1056     lsh r9, 32
1057     mov32 r0, 0
1058     mov32 r1, 0xb
1059     or r1, r9
1060     mov32 r2, 0xb
1061     jne32 r1, r2, +4
1062     mov32 r0, 1
1063     mov32 r1, 0xa
1064     or r1, r9
1065     jne32 r1, r2, +1
1066     mov32 r0, 2
1067     exit
1068     ",
1069     0x1
1070 );
1071 
1072 test_cranelift!(
1073     test_cranelift_jset32_imm,
1074     "
1075     mov r9, 1
1076     lsh r9, 32
1077     mov32 r0, 0
1078     mov32 r1, 0x7
1079     or r1, r9
1080     jset32 r1, 0x8, +4
1081     mov32 r0, 1
1082     mov32 r1, 0x9
1083     jset32 r1, 0x8, +1
1084     mov32 r0, 2
1085     exit
1086     ",
1087     0x1
1088 );
1089 
1090 test_cranelift!(
1091     test_cranelift_jset32_reg,
1092     "
1093     mov r9, 1
1094     lsh r9, 32
1095     mov32 r0, 0
1096     mov32 r1, 0x7
1097     or r1, r9
1098     mov32 r2, 0x8
1099     jset32 r1, r2, +4
1100     mov32 r0, 1
1101     mov32 r1, 0x9
1102     jset32 r1, r2, +1
1103     mov32 r0, 2
1104     exit
1105     ",
1106     0x1
1107 );
1108 
1109 test_cranelift!(
1110     test_cranelift_jsge32_imm,
1111     "
1112     mov r9, 1
1113     lsh r9, 32
1114     mov32 r0, 0
1115     mov32 r1, -2
1116     or r1, r9
1117     jsge32 r1, -1, +5
1118     jsge32 r1, 0, +4
1119     mov32 r0, 1
1120     mov r1, -1
1121     jsge32 r1, -1, +1
1122     mov32 r0, 2
1123     exit
1124     ",
1125     0x1
1126 );
1127 
1128 test_cranelift!(
1129     test_cranelift_jsge32_reg,
1130     "
1131     mov r9, 1
1132     lsh r9, 32
1133     mov32 r0, 0
1134     mov32 r1, -2
1135     or r1, r9
1136     mov r2, -1
1137     mov32 r3, 0
1138     jsge32 r1, r2, +5
1139     jsge32 r1, r3, +4
1140     mov32 r0, 1
1141     mov r1, r2
1142     jsge32 r1, r2, +1
1143     mov32 r0, 2
1144     exit
1145     ",
1146     0x1
1147 );
1148 
1149 test_cranelift!(
1150     test_cranelift_jsgt32_imm,
1151     "
1152     mov r9, 1
1153     lsh r9, 32
1154     mov32 r0, 0
1155     mov32 r1, -2
1156     or r1, r9
1157     jsgt32 r1, -1, +4
1158     mov32 r0, 1
1159     mov32 r1, 0
1160     jsgt32 r1, -1, +1
1161     mov32 r0, 2
1162     exit
1163     ",
1164     0x1
1165 );
1166 
1167 test_cranelift!(
1168     test_cranelift_jsgt32_reg,
1169     "
1170     mov r9, 1
1171     lsh r9, 32
1172     mov32 r0, 0
1173     mov32 r1, -2
1174     or r1, r9
1175     mov r2, -1
1176     jsgt32 r1, r2, +4
1177     mov32 r0, 1
1178     mov32 r1, 0
1179     jsgt32 r1, r2, +1
1180     mov32 r0, 2
1181     exit
1182     ",
1183     0x1
1184 );
1185 
1186 test_cranelift!(
1187     test_cranelift_jsle32_imm,
1188     "
1189     mov r9, 1
1190     lsh r9, 32
1191     mov32 r0, 0
1192     mov32 r1, -2
1193     or r1, r9
1194     jsle32 r1, -3, +5
1195     jsle32 r1, -1, +1
1196     exit
1197     mov32 r0, 1
1198     jsle32 r1, -2, +1
1199     mov32 r0, 2
1200     exit
1201     ",
1202     0x1
1203 );
1204 
1205 test_cranelift!(
1206     test_cranelift_jsle32_reg,
1207     "
1208     mov r9, 1
1209     lsh r9, 32
1210     mov32 r0, 0
1211     mov32 r1, -2
1212     or r1, r9
1213     mov r2, -3
1214     mov32 r3, 0
1215     jsle32 r1, r2, +6
1216     jsle32 r1, r3, +1
1217     exit
1218     mov32 r0, 1
1219     mov r1, r2
1220     jsle32 r1, r2, +1
1221     mov32 r0, 2
1222     exit
1223     ",
1224     0x1
1225 );
1226 
1227 test_cranelift!(
1228     test_cranelift_jslt32_imm,
1229     "
1230     mov r9, 1
1231     lsh r9, 32
1232     mov32 r0, 0
1233     mov32 r1, -2
1234     or r1, r9
1235     jslt32 r1, -3, +4
1236     jslt32 r1, -2, +3
1237     jslt32 r1, -1, +1
1238     exit
1239     mov32 r0, 1
1240     exit
1241     ",
1242     0x1
1243 );
1244 
1245 test_cranelift!(
1246     test_cranelift_jslt32_reg,
1247     "
1248     mov r9, 1
1249     lsh r9, 32
1250     mov32 r0, 0
1251     mov32 r1, -2
1252     or r1, r9
1253     mov r2, -3
1254     mov r3, -1
1255     jslt32 r1, r1, +4
1256     jslt32 r1, r2, +3
1257     jslt32 r1, r3, +1
1258     exit
1259     mov32 r0, 1
1260     exit
1261     ",
1262     0x1
1263 );
1264 
1265 test_cranelift!(
1266     test_cranelift_lddw,
1267     "
1268     lddw r0, 0x1122334455667788
1269     exit
1270     ",
1271     0x1122334455667788
1272 );
1273 
1274 test_cranelift!(
1275     test_cranelift_lddw2,
1276     "
1277     lddw r0, 0x0000000080000000
1278     exit
1279     ",
1280     0x80000000
1281 );
1282 
1283 test_cranelift!(
1284     test_cranelift_ldxb_all,
1285     "
1286     mov r0, r1
1287     ldxb r9, [r0+0]
1288     lsh r9, 0
1289     ldxb r8, [r0+1]
1290     lsh r8, 4
1291     ldxb r7, [r0+2]
1292     lsh r7, 8
1293     ldxb r6, [r0+3]
1294     lsh r6, 12
1295     ldxb r5, [r0+4]
1296     lsh r5, 16
1297     ldxb r4, [r0+5]
1298     lsh r4, 20
1299     ldxb r3, [r0+6]
1300     lsh r3, 24
1301     ldxb r2, [r0+7]
1302     lsh r2, 28
1303     ldxb r1, [r0+8]
1304     lsh r1, 32
1305     ldxb r0, [r0+9]
1306     lsh r0, 36
1307     or r0, r1
1308     or r0, r2
1309     or r0, r3
1310     or r0, r4
1311     or r0, r5
1312     or r0, r6
1313     or r0, r7
1314     or r0, r8
1315     or r0, r9
1316     exit
1317     ",
1318     [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09],
1319     0x9876543210
1320 );
1321 
1322 test_cranelift!(
1323     test_cranelift_ldxb,
1324     "
1325     ldxb r0, [r1+2]
1326     exit
1327     ",
1328     [0xaa, 0xbb, 0x11, 0xcc, 0xdd],
1329     0x11
1330 );
1331 
1332 test_cranelift!(
1333     test_cranelift_ldxdw,
1334     "
1335     ldxdw r0, [r1+2]
1336     exit
1337     ",
1338     [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xcc, 0xdd],
1339     0x8877665544332211
1340 );
1341 
1342 test_cranelift!(
1343     test_cranelift_ldxh_all,
1344     "
1345     mov r0, r1
1346     ldxh r9, [r0+0]
1347     be16 r9
1348     lsh r9, 0
1349     ldxh r8, [r0+2]
1350     be16 r8
1351     lsh r8, 4
1352     ldxh r7, [r0+4]
1353     be16 r7
1354     lsh r7, 8
1355     ldxh r6, [r0+6]
1356     be16 r6
1357     lsh r6, 12
1358     ldxh r5, [r0+8]
1359     be16 r5
1360     lsh r5, 16
1361     ldxh r4, [r0+10]
1362     be16 r4
1363     lsh r4, 20
1364     ldxh r3, [r0+12]
1365     be16 r3
1366     lsh r3, 24
1367     ldxh r2, [r0+14]
1368     be16 r2
1369     lsh r2, 28
1370     ldxh r1, [r0+16]
1371     be16 r1
1372     lsh r1, 32
1373     ldxh r0, [r0+18]
1374     be16 r0
1375     lsh r0, 36
1376     or r0, r1
1377     or r0, r2
1378     or r0, r3
1379     or r0, r4
1380     or r0, r5
1381     or r0, r6
1382     or r0, r7
1383     or r0, r8
1384     or r0, r9
1385     exit
1386     ",
1387     [
1388         0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00,
1389         0x07, 0x00, 0x08, 0x00, 0x09
1390     ],
1391     0x9876543210
1392 );
1393 
1394 test_cranelift!(
1395     test_cranelift_ldxh_all2,
1396     "
1397     mov r0, r1
1398     ldxh r9, [r0+0]
1399     be16 r9
1400     ldxh r8, [r0+2]
1401     be16 r8
1402     ldxh r7, [r0+4]
1403     be16 r7
1404     ldxh r6, [r0+6]
1405     be16 r6
1406     ldxh r5, [r0+8]
1407     be16 r5
1408     ldxh r4, [r0+10]
1409     be16 r4
1410     ldxh r3, [r0+12]
1411     be16 r3
1412     ldxh r2, [r0+14]
1413     be16 r2
1414     ldxh r1, [r0+16]
1415     be16 r1
1416     ldxh r0, [r0+18]
1417     be16 r0
1418     or r0, r1
1419     or r0, r2
1420     or r0, r3
1421     or r0, r4
1422     or r0, r5
1423     or r0, r6
1424     or r0, r7
1425     or r0, r8
1426     or r0, r9
1427     exit
1428     ",
1429     [
1430         0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00,
1431         0x80, 0x01, 0x00, 0x02, 0x00
1432     ],
1433     0x3ff
1434 );
1435 
1436 test_cranelift!(
1437     test_cranelift_ldxh,
1438     "
1439     ldxh r0, [r1+2]
1440     exit
1441     ",
1442     [0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd],
1443     0x2211
1444 );
1445 
1446 test_cranelift!(
1447     test_cranelift_ldxh_same_reg,
1448     "
1449     mov r0, r1
1450     sth [r0], 0x1234
1451     ldxh r0, [r0]
1452     exit
1453     ",
1454     [0xff, 0xff],
1455     0x1234
1456 );
1457 
1458 test_cranelift!(
1459     test_cranelift_ldxw_all,
1460     "
1461     mov r0, r1
1462     ldxw r9, [r0+0]
1463     be32 r9
1464     ldxw r8, [r0+4]
1465     be32 r8
1466     ldxw r7, [r0+8]
1467     be32 r7
1468     ldxw r6, [r0+12]
1469     be32 r6
1470     ldxw r5, [r0+16]
1471     be32 r5
1472     ldxw r4, [r0+20]
1473     be32 r4
1474     ldxw r3, [r0+24]
1475     be32 r3
1476     ldxw r2, [r0+28]
1477     be32 r2
1478     ldxw r1, [r0+32]
1479     be32 r1
1480     ldxw r0, [r0+36]
1481     be32 r0
1482     or r0, r1
1483     or r0, r2
1484     or r0, r3
1485     or r0, r4
1486     or r0, r5
1487     or r0, r6
1488     or r0, r7
1489     or r0, r8
1490     or r0, r9
1491     exit
1492     ",
1493     [
1494         0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1495         0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1496         0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
1497     ],
1498     0x030f0f
1499 );
1500 
1501 test_cranelift!(
1502     test_cranelift_ldxw,
1503     "
1504     ldxw r0, [r1+2]
1505     exit
1506     ",
1507     [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0xcc, 0xdd],
1508     0x44332211
1509 );
1510 
1511 test_cranelift!(
1512     test_cranelift_le16,
1513     "
1514     ldxh r0, [r1]
1515     le16 r0
1516     exit
1517     ",
1518     [0x22, 0x11],
1519     0x1122
1520 );
1521 
1522 test_cranelift!(
1523     test_cranelift_le32,
1524     "
1525     ldxw r0, [r1]
1526     le32 r0
1527     exit
1528     ",
1529     [0x44, 0x33, 0x22, 0x11],
1530     0x11223344
1531 );
1532 
1533 test_cranelift!(
1534     test_cranelift_le64,
1535     "
1536     ldxdw r0, [r1]
1537     le64 r0
1538     exit
1539     ",
1540     [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11],
1541     0x1122334455667788
1542 );
1543 
1544 test_cranelift!(
1545     test_cranelift_lsh_reg,
1546     "
1547     mov r0, 0x1
1548     mov r7, 4
1549     lsh r0, r7
1550     exit
1551     ",
1552     0x10
1553 );
1554 
1555 test_cranelift!(
1556     test_cranelift_mod,
1557     "
1558     mov32 r0, 5748
1559     mod32 r0, 92
1560     mov32 r1, 13
1561     mod32 r0, r1
1562     exit
1563     ",
1564     0x5
1565 );
1566 
1567 test_cranelift!(
1568     test_cranelift_mod32,
1569     "
1570     lddw r0, 0x100000003
1571     mod32 r0, 3
1572     exit
1573     ",
1574     0x0
1575 );
1576 
1577 test_cranelift!(
1578     test_cranelift_mod64,
1579     "
1580     mov32 r0, -1316649930
1581     lsh r0, 32
1582     or r0, 0x100dc5c8
1583     mov32 r1, 0xdde263e
1584     lsh r1, 32
1585     or r1, 0x3cbef7f3
1586     mod r0, r1
1587     mod r0, 0x658f1778
1588     exit
1589     ",
1590     0x30ba5a04
1591 );
1592 
1593 test_cranelift!(
1594     test_cranelift_mov,
1595     "
1596     mov32 r1, 1
1597     mov32 r0, r1
1598     exit
1599     ",
1600     0x1
1601 );
1602 
1603 test_cranelift!(
1604     test_cranelift_mul32_imm,
1605     "
1606     mov r0, 3
1607     mul32 r0, 4
1608     exit
1609     ",
1610     0xc
1611 );
1612 
1613 test_cranelift!(
1614     test_cranelift_mul32_reg,
1615     "
1616     mov r0, 3
1617     mov r1, 4
1618     mul32 r0, r1
1619     exit
1620     ",
1621     0xc
1622 );
1623 
1624 test_cranelift!(
1625     test_cranelift_mul32_reg_overflow,
1626     "
1627     mov r0, 0x40000001
1628     mov r1, 4
1629     mul32 r0, r1
1630     exit
1631     ",
1632     0x4
1633 );
1634 
1635 test_cranelift!(
1636     test_cranelift_mul64_imm,
1637     "
1638     mov r0, 0x40000001
1639     mul r0, 4
1640     exit
1641     ",
1642     0x100000004
1643 );
1644 
1645 test_cranelift!(
1646     test_cranelift_mul64_reg,
1647     "
1648     mov r0, 0x40000001
1649     mov r1, 4
1650     mul r0, r1
1651     exit
1652     ",
1653     0x100000004
1654 );
1655 
1656 test_cranelift!(
1657     test_cranelift_mul_loop,
1658     "
1659     mov r0, 0x7
1660     add r1, 0xa
1661     lsh r1, 0x20
1662     rsh r1, 0x20
1663     jeq r1, 0x0, +4
1664     mov r0, 0x7
1665     mul r0, 0x7
1666     add r1, -1
1667     jne r1, 0x0, -3
1668     exit
1669     ",
1670     0x75db9c97
1671 );
1672 
1673 test_cranelift!(
1674     test_cranelift_neg64,
1675     "
1676     mov32 r0, 2
1677     neg r0
1678     exit
1679     ",
1680     0xfffffffffffffffe
1681 );
1682 
1683 test_cranelift!(
1684     test_cranelift_neg,
1685     "
1686     mov32 r0, 2
1687     neg32 r0
1688     exit
1689     ",
1690     0xfffffffe
1691 );
1692 
1693 test_cranelift!(
1694     test_cranelift_prime,
1695     "
1696     mov r1, 67
1697     mov r0, 0x1
1698     mov r2, 0x2
1699     jgt r1, 0x2, +4
1700     ja +10
1701     add r2, 0x1
1702     mov r0, 0x1
1703     jge r2, r1, +7
1704     mov r3, r1
1705     div r3, r2
1706     mul r3, r2
1707     mov r4, r1
1708     sub r4, r3
1709     mov r0, 0x0
1710     jne r4, 0x0, -10
1711     exit
1712     ",
1713     1
1714 );
1715 
1716 test_cranelift!(
1717     test_cranelift_rhs32,
1718     "
1719     xor r0, r0
1720     sub r0, 1
1721     rsh32 r0, 8
1722     exit
1723     ",
1724     0x00ffffff
1725 );
1726 
1727 test_cranelift!(
1728     test_cranelift_rsh_reg,
1729     "
1730     mov r0, 0x10
1731     mov r7, 4
1732     rsh r0, r7
1733     exit
1734     ",
1735     0x1
1736 );
1737 
1738 test_cranelift!(
1739     test_cranelift_stack,
1740     "
1741     mov r1, 51
1742     stdw [r10-16], 0xab
1743     stdw [r10-8], 0xcd
1744     and r1, 1
1745     lsh r1, 3
1746     mov r2, r10
1747     add r2, r1
1748     ldxdw r0, [r2-16]
1749     exit
1750     ",
1751     0xcd
1752 );
1753 
1754 #[test]
1755 fn test_cranelift_stack2() {
1756     let prog = assemble(
1757         "
1758         stb [r10-4], 0x01
1759         stb [r10-3], 0x02
1760         stb [r10-2], 0x03
1761         stb [r10-1], 0x04
1762         mov r1, r10
1763         mov r2, 0x4
1764         sub r1, r2
1765         call 1
1766         mov r1, 0
1767         ldxb r2, [r10-4]
1768         ldxb r3, [r10-3]
1769         ldxb r4, [r10-2]
1770         ldxb r5, [r10-1]
1771         call 0
1772         xor r0, 0x2a2a2a2a
1773         exit",
1774     )
1775     .unwrap();
1776 
1777     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1778     vm.register_helper(0, helpers::gather_bytes).unwrap();
1779     vm.register_helper(1, helpers::memfrob).unwrap();
1780     vm.cranelift_compile().unwrap();
1781     assert_eq!(vm.execute_program_cranelift().unwrap(), 0x01020304);
1782 }
1783 
1784 test_cranelift!(
1785     test_cranelift_stb,
1786     "
1787     stb [r1+2], 0x11
1788     ldxb r0, [r1+2]
1789     exit
1790     ",
1791     [0xaa, 0xbb, 0xff, 0xcc, 0xdd],
1792     0x11
1793 );
1794 
1795 test_cranelift!(
1796     test_cranelift_stdw,
1797     "
1798     stdw [r1+2], 0x44332211
1799     ldxdw r0, [r1+2]
1800     exit
1801     ",
1802     [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1803     0x44332211
1804 );
1805 
1806 test_cranelift!(
1807     test_cranelift_sth,
1808     "
1809     sth [r1+2], 0x2211
1810     ldxh r0, [r1+2]
1811     exit
1812     ",
1813     [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd],
1814     0x2211
1815 );
1816 
1817 #[test]
1818 #[ignore]
1819 fn test_cranelift_string_stack() {
1820     let prog = assemble(
1821         "
1822         mov r1, 0x78636261
1823         stxw [r10-8], r1
1824         mov r6, 0x0
1825         stxb [r10-4], r6
1826         stxb [r10-12], r6
1827         mov r1, 0x79636261
1828         stxw [r10-16], r1
1829         mov r1, r10
1830         add r1, -8
1831         mov r2, r1
1832         call 0x4
1833         mov r1, r0
1834         mov r0, 0x1
1835         lsh r1, 0x20
1836         rsh r1, 0x20
1837         jne r1, 0x0, +11
1838         mov r1, r10
1839         add r1, -8
1840         mov r2, r10
1841         add r2, -16
1842         call 0x4
1843         mov r1, r0
1844         lsh r1, 0x20
1845         rsh r1, 0x20
1846         mov r0, 0x1
1847         jeq r1, r6, +1
1848         mov r0, 0x0
1849         exit",
1850     )
1851     .unwrap();
1852 
1853     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
1854     vm.register_helper(4, helpers::strcmp).unwrap();
1855     vm.cranelift_compile().unwrap();
1856     assert_eq!(vm.execute_program_cranelift().unwrap(), 0x0);
1857 }
1858 
1859 test_cranelift!(
1860     test_cranelift_stw,
1861     "
1862     stw [r1+2], 0x44332211
1863     ldxw r0, [r1+2]
1864     exit
1865     ",
1866     [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1867     0x44332211
1868 );
1869 
1870 test_cranelift!(
1871     test_cranelift_stxb,
1872     "
1873     mov32 r2, 0x11
1874     stxb [r1+2], r2
1875     ldxb r0, [r1+2]
1876     exit
1877     ",
1878     [0xaa, 0xbb, 0xff, 0xcc, 0xdd],
1879     0x11
1880 );
1881 
1882 test_cranelift!(
1883     test_cranelift_stxb_all,
1884     "
1885     mov r0, 0xf0
1886     mov r2, 0xf2
1887     mov r3, 0xf3
1888     mov r4, 0xf4
1889     mov r5, 0xf5
1890     mov r6, 0xf6
1891     mov r7, 0xf7
1892     mov r8, 0xf8
1893     stxb [r1], r0
1894     stxb [r1+1], r2
1895     stxb [r1+2], r3
1896     stxb [r1+3], r4
1897     stxb [r1+4], r5
1898     stxb [r1+5], r6
1899     stxb [r1+6], r7
1900     stxb [r1+7], r8
1901     ldxdw r0, [r1]
1902     be64 r0
1903     exit
1904     ",
1905     [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1906     0xf0f2f3f4f5f6f7f8
1907 );
1908 
1909 test_cranelift!(
1910     test_cranelift_stxb_all2,
1911     "
1912     mov r0, r1
1913     mov r1, 0xf1
1914     mov r9, 0xf9
1915     stxb [r0], r1
1916     stxb [r0+1], r9
1917     ldxh r0, [r0]
1918     be16 r0
1919     exit
1920     ",
1921     [0xff, 0xff],
1922     0xf1f9
1923 );
1924 
1925 test_cranelift!(
1926     test_cranelift_stxb_chain,
1927     "
1928     mov r0, r1
1929     ldxb r9, [r0+0]
1930     stxb [r0+1], r9
1931     ldxb r8, [r0+1]
1932     stxb [r0+2], r8
1933     ldxb r7, [r0+2]
1934     stxb [r0+3], r7
1935     ldxb r6, [r0+3]
1936     stxb [r0+4], r6
1937     ldxb r5, [r0+4]
1938     stxb [r0+5], r5
1939     ldxb r4, [r0+5]
1940     stxb [r0+6], r4
1941     ldxb r3, [r0+6]
1942     stxb [r0+7], r3
1943     ldxb r2, [r0+7]
1944     stxb [r0+8], r2
1945     ldxb r1, [r0+8]
1946     stxb [r0+9], r1
1947     ldxb r0, [r0+9]
1948     exit
1949     ",
1950     [0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
1951     0x2a
1952 );
1953 
1954 test_cranelift!(
1955     test_cranelift_stxdw,
1956     "
1957     mov r2, -2005440939
1958     lsh r2, 32
1959     or r2, 0x44332211
1960     stxdw [r1+2], r2
1961     ldxdw r0, [r1+2]
1962     exit
1963     ",
1964     [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1965     0x8877665544332211
1966 );
1967 
1968 test_cranelift!(
1969     test_cranelift_stxh,
1970     "
1971     mov32 r2, 0x2211
1972     stxh [r1+2], r2
1973     ldxh r0, [r1+2]
1974     exit
1975     ",
1976     [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd],
1977     0x2211
1978 );
1979 
1980 test_cranelift!(
1981     test_cranelift_stxw,
1982     "
1983     mov32 r2, 0x44332211
1984     stxw [r1+2], r2
1985     ldxw r0, [r1+2]
1986     exit
1987     ",
1988     [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
1989     0x44332211
1990 );
1991 
1992 test_cranelift!(
1993     test_cranelift_subnet,
1994     "
1995     mov r2, 0xe
1996     ldxh r3, [r1+12]
1997     jne r3, 0x81, +2
1998     mov r2, 0x12
1999     ldxh r3, [r1+16]
2000     and r3, 0xffff
2001     jne r3, 0x8, +5
2002     add r1, r2
2003     mov r0, 0x1
2004     ldxw r1, [r1+16]
2005     and r1, 0xffffff
2006     jeq r1, 0x1a8c0, +1
2007     mov r0, 0x0
2008     exit
2009     ",
2010     [
2011         0x00, 0x00, 0xc0, 0x9f, 0xa0, 0x97, 0x00, 0xa0, 0xcc, 0x3b, 0xbf, 0xfa, 0x08, 0x00, 0x45,
2012         0x10, 0x00, 0x3c, 0x46, 0x3c, 0x40, 0x00, 0x40, 0x06, 0x73, 0x1c, 0xc0, 0xa8, 0x01, 0x02,
2013         0xc0, 0xa8, 0x01, 0x01, 0x06, 0x0e, 0x00, 0x17, 0x99, 0xc5, 0xa0, 0xec, 0x00, 0x00, 0x00,
2014         0x00, 0xa0, 0x02, 0x7d, 0x78, 0xe0, 0xa3, 0x00, 0x00, 0x02, 0x04, 0x05, 0xb4, 0x04, 0x02,
2015         0x08, 0x0a, 0x00, 0x9c, 0x27, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00,
2016     ],
2017     0x1
2018 );
2019 
2020 const PROG_TCP_PORT_80: [u8; 152] = [
2021     0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
2022     0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2023     0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
2024     0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
2025     0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2026     0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2027     0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
2028     0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2029     0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2030     0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2031 ];
2032 
2033 #[test]
2034 fn test_cranelift_tcp_port80_match() {
2035     let mem = &mut [
2036         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2037         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2038         0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2039         0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2040         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2041         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2042         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2043     ];
2044     let prog = &PROG_TCP_PORT_80;
2045     let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2046     vm.cranelift_compile().unwrap();
2047     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x1);
2048 }
2049 
2050 #[test]
2051 fn test_cranelift_tcp_port80_nomatch() {
2052     let mem = &mut [
2053         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2054         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2055         0xc0, 0xa8, 0x00, 0x02, 0x00, 0x16, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2056         0x00, 0x51, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2057         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2058         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2059         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2060     ];
2061     let prog = &PROG_TCP_PORT_80;
2062     let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2063     vm.cranelift_compile().unwrap();
2064     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x0);
2065 }
2066 
2067 #[test]
2068 fn test_cranelift_tcp_port80_nomatch_ethertype() {
2069     let mem = &mut [
2070         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x01, 0x45,
2071         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2072         0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2073         0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2074         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2075         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2076         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2077     ];
2078     let prog = &PROG_TCP_PORT_80;
2079     let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2080     vm.cranelift_compile().unwrap();
2081     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x0);
2082 }
2083 
2084 #[test]
2085 fn test_cranelift_tcp_port80_nomatch_proto() {
2086     let mem = &mut [
2087         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
2088         0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
2089         0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090         0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2091         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2092         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2093         0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2094     ];
2095     let prog = &PROG_TCP_PORT_80;
2096     let mut vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
2097     vm.cranelift_compile().unwrap();
2098     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x0);
2099 }
2100 
2101 #[test]
2102 fn test_cranelift_tcp_sack_match() {
2103     let mut mem = TCP_SACK_MATCH.to_vec();
2104     let prog = assemble(TCP_SACK_ASM).unwrap();
2105     let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2106     vm.cranelift_compile().unwrap();
2107     assert_eq!(
2108         vm.execute_program_cranelift(mem.as_mut_slice()).unwrap(),
2109         0x1
2110     );
2111 }
2112 
2113 #[test]
2114 fn test_cranelift_tcp_sack_nomatch() {
2115     let mut mem = TCP_SACK_NOMATCH.to_vec();
2116     let prog = assemble(TCP_SACK_ASM).unwrap();
2117     let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
2118     vm.cranelift_compile().unwrap();
2119     assert_eq!(
2120         vm.execute_program_cranelift(mem.as_mut_slice()).unwrap(),
2121         0x0
2122     );
2123 }
2124 
2125 #[test]
2126 fn test_cranelift_ldabsb() {
2127     let prog = &[
2128         0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2129         0x00,
2130     ];
2131     let mem = &mut [
2132         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2133         0xff,
2134     ];
2135     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2136 
2137     vm.cranelift_compile().unwrap();
2138     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x33);
2139 }
2140 
2141 #[test]
2142 fn test_cranelift_ldabsh() {
2143     let prog = &[
2144         0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2145         0x00,
2146     ];
2147     let mem = &mut [
2148         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2149         0xff,
2150     ];
2151     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2152 
2153     vm.cranelift_compile().unwrap();
2154     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x4433);
2155 }
2156 
2157 #[test]
2158 fn test_cranelift_ldabsw() {
2159     let prog = &[
2160         0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2161         0x00,
2162     ];
2163     let mem = &mut [
2164         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2165         0xff,
2166     ];
2167     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2168 
2169     vm.cranelift_compile().unwrap();
2170     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x66554433);
2171 }
2172 
2173 #[test]
2174 fn test_cranelift_ldabsdw() {
2175     let prog = &[
2176         0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2177         0x00,
2178     ];
2179     let mem = &mut [
2180         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2181         0xff,
2182     ];
2183     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2184 
2185     vm.cranelift_compile().unwrap();
2186     assert_eq!(
2187         vm.execute_program_cranelift(mem).unwrap(),
2188         0xaa99887766554433
2189     );
2190 }
2191 
2192 #[test]
2193 fn test_cranelift_ldindb() {
2194     let prog = &[
2195         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00,
2196         0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2197     ];
2198     let mem = &mut [
2199         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2200         0xff,
2201     ];
2202     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2203 
2204     vm.cranelift_compile().unwrap();
2205     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x88);
2206 }
2207 
2208 #[test]
2209 fn test_cranelift_ldindh() {
2210     let prog = &[
2211         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00,
2212         0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2213     ];
2214     let mem = &mut [
2215         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2216         0xff,
2217     ];
2218     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2219 
2220     vm.cranelift_compile().unwrap();
2221     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x9988);
2222 }
2223 
2224 #[test]
2225 fn test_cranelift_ldindw() {
2226     let prog = &[
2227         0xb7, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00,
2228         0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2229     ];
2230     let mem = &mut [
2231         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2232         0xff,
2233     ];
2234     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2235 
2236     vm.cranelift_compile().unwrap();
2237     assert_eq!(vm.execute_program_cranelift(mem).unwrap(), 0x88776655);
2238 }
2239 
2240 #[test]
2241 fn test_cranelift_ldinddw() {
2242     let prog = &[
2243         0xb7, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00,
2244         0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2245     ];
2246     let mem = &mut [
2247         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
2248         0xff,
2249     ];
2250     let mut vm = rbpf::EbpfVmFixedMbuff::new(Some(prog), 0x00, 0x08).unwrap();
2251 
2252     vm.cranelift_compile().unwrap();
2253     assert_eq!(
2254         vm.execute_program_cranelift(mem).unwrap(),
2255         0xccbbaa9988776655
2256     );
2257 }
2258