1#![allow(clippy::too_many_arguments)]
78
79pub mod interpretations;
80use crate::abstractions::{bit::*, bitvec::*, funarr::*};
81
82pub(crate) mod upstream {
83 #[cfg(target_arch = "x86")]
84 pub use core::arch::x86::*;
85 #[cfg(target_arch = "x86_64")]
86 pub use core::arch::x86_64::*;
87}
88
89#[hax_lib::exclude]
91#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
92mod conversions {
93 use super::upstream::{
94 __m128i, __m256, __m256i, _mm256_castps_si256, _mm256_castsi256_ps, _mm256_loadu_si256,
95 _mm256_storeu_si256, _mm_loadu_si128, _mm_storeu_si128,
96 };
97 use super::BitVec;
98
99 impl From<BitVec<256>> for __m256i {
100 fn from(bv: BitVec<256>) -> __m256i {
101 let bv: &[u8] = &bv.to_vec()[..];
102 unsafe { _mm256_loadu_si256(bv.as_ptr() as *const _) }
103 }
104 }
105 impl From<BitVec<256>> for __m256 {
106 fn from(bv: BitVec<256>) -> __m256 {
107 let bv: &[u8] = &bv.to_vec()[..];
108 unsafe { _mm256_castsi256_ps(_mm256_loadu_si256(bv.as_ptr() as *const _)) }
109 }
110 }
111
112 impl From<BitVec<128>> for __m128i {
113 fn from(bv: BitVec<128>) -> __m128i {
114 let slice: &[u8] = &bv.to_vec()[..];
115 unsafe { _mm_loadu_si128(slice.as_ptr() as *const __m128i) }
116 }
117 }
118
119 impl From<__m256i> for BitVec<256> {
120 fn from(vec: __m256i) -> BitVec<256> {
121 let mut v = [0u8; 32];
122 unsafe {
123 _mm256_storeu_si256(v.as_mut_ptr() as *mut _, vec);
124 }
125 BitVec::from_slice(&v[..], 8)
126 }
127 }
128
129 impl From<__m256> for BitVec<256> {
130 fn from(vec: __m256) -> BitVec<256> {
131 let mut v = [0u8; 32];
132 unsafe {
133 _mm256_storeu_si256(v.as_mut_ptr() as *mut _, _mm256_castps_si256(vec));
134 }
135 BitVec::from_slice(&v[..], 8)
136 }
137 }
138
139 impl From<__m128i> for BitVec<128> {
140 fn from(vec: __m128i) -> BitVec<128> {
141 let mut v = [0u8; 16];
142 unsafe {
143 _mm_storeu_si128(v.as_mut_ptr() as *mut _, vec);
144 }
145 BitVec::from_slice(&v[..], 8)
146 }
147 }
148}
149
150#[hax_lib::fstar::replace(
151 r#"
152 unfold type t_e_ee_m256i = $:{__m256i}
153 unfold type t_e_ee_m128i = $:{__m128i}
154"#
155)]
156const _: () = {};
157
158#[allow(non_camel_case_types)]
161pub type __m256i = BitVec<256>;
162
163#[allow(non_camel_case_types)]
166pub type __m128i = BitVec<128>;
167
168#[allow(non_camel_case_types)]
171pub type __m256 = __m256i;
172
173pub use ssse3::*;
174pub mod ssse3 {
175 use super::*;
176 #[hax_lib::opaque]
177 pub fn _mm_shuffle_epi8(vector: __m128i, indexes: __m128i) -> __m128i {
178 let indexes = indexes.to_vec().try_into().unwrap();
179 extra::mm_shuffle_epi8_u8_array(vector, indexes)
180 }
181}
182pub use sse2::*;
183pub mod sse2 {
184 #[hax_lib::exclude]
187 pub unsafe fn _mm_loadu_si128(_mem_addr: *const __m128i) -> __m128i {
188 unimplemented!()
189 }
190
191 #[hax_lib::opaque]
193 pub fn _mm_packs_epi16(_: __m128i, _: __m128i) -> __m128i {
194 unimplemented!()
195 }
196
197 use super::*;
198 #[hax_lib::opaque]
199 pub fn _mm_set_epi8(
200 _e15: i8,
201 _e14: i8,
202 _e13: i8,
203 _e12: i8,
204 _e11: i8,
205 _e10: i8,
206 _e9: i8,
207 _e8: i8,
208 _e7: i8,
209 _e6: i8,
210 _e5: i8,
211 _e4: i8,
212 _e3: i8,
213 _e2: i8,
214 _e1: i8,
215 _e0: i8,
216 ) -> __m128i {
217 todo!()
218 }
219
220 #[hax_lib::opaque]
222 pub fn _mm_set1_epi16(_: i16) -> __m128i {
223 unimplemented!()
224 }
225 #[hax_lib::opaque]
227 pub fn _mm_set_epi32(_: i32, _: i32, _: i32, _: i32) -> __m128i {
228 unimplemented!()
229 }
230
231 #[hax_lib::opaque]
233 pub fn _mm_add_epi16(_: __m128i, _: __m128i) -> __m128i {
234 unimplemented!()
235 }
236 #[hax_lib::opaque]
238 pub fn _mm_sub_epi16(_: __m128i, _: __m128i) -> __m128i {
239 unimplemented!()
240 }
241 #[hax_lib::opaque]
243 pub fn _mm_mullo_epi16(_: __m128i, _: __m128i) -> __m128i {
244 unimplemented!()
245 }
246
247 #[hax_lib::opaque]
249 pub fn _mm_mulhi_epi16(_: __m128i, _: __m128i) -> __m128i {
250 unimplemented!()
251 }
252 #[hax_lib::opaque]
254 pub fn _mm_srli_epi64<const IMM8: i32>(_: __m128i) -> __m128i {
255 unimplemented!()
256 }
257
258 #[hax_lib::opaque]
260 pub fn _mm_movemask_epi8(_: __m128i) -> i32 {
261 unimplemented!()
262 }
263
264 #[hax_lib::opaque]
266 pub fn _mm_unpacklo_epi64(_: __m128i, _: __m128i) -> __m128i {
267 unimplemented!()
268 }
269
270 #[hax_lib::opaque]
272 pub fn _mm_unpackhi_epi64(_: __m128i, _: __m128i) -> __m128i {
273 unimplemented!()
274 }
275
276 #[hax_lib::opaque]
278 pub fn _mm_shuffle_epi32<const IMM8: i32>(_: __m128i) -> __m128i {
279 unimplemented!()
280 }
281
282 #[hax_lib::opaque]
284 pub fn _mm_srli_si128<const IMM8: i32>(_: __m128i) -> __m128i {
285 unimplemented!()
286 }
287
288 #[hax_lib::opaque]
290 pub fn _mm_slli_si128<const IMM8: i32>(_: __m128i) -> __m128i {
291 unimplemented!()
292 }
293
294 #[hax_lib::opaque]
296 pub fn _mm_xor_si128(_: __m128i, _: __m128i) -> __m128i {
297 unimplemented!()
298 }
299
300 #[hax_lib::opaque]
302 pub fn _mm_setzero_si128() -> __m128i {
303 unimplemented!()
304 }
305}
306
307pub use avx::*;
308pub mod avx {
309 #[hax_lib::exclude]
312 pub unsafe fn _mm256_storeu_si256(_mem_addr: *mut __m256i, _a: __m256i) {
313 unimplemented!()
314 }
315
316 #[hax_lib::exclude]
319 pub unsafe fn _mm256_loadu_si256(_mem_addr: *const __m256i) -> __m256i {
320 unimplemented!()
321 }
322
323 #[hax_lib::opaque]
325 pub fn _mm256_set1_epi64x(_: i64) -> __m256i {
326 unimplemented!()
327 }
328 #[hax_lib::opaque]
330 pub fn _mm256_set_epi64x(_: i64, _: i64, _: i64, _: i64) -> __m256i {
331 unimplemented!()
332 }
333 #[hax_lib::opaque]
335 pub fn _mm256_blendv_ps(_: __m256, _: __m256, _: __m256) -> __m256 {
336 unimplemented!()
337 }
338 #[hax_lib::opaque]
340 pub fn _mm256_castsi128_si256(_: __m128i) -> __m256i {
341 unimplemented!()
342 }
343 #[hax_lib::opaque]
345 pub fn _mm256_testz_si256(_: __m256i, _: __m256i) -> i32 {
346 unimplemented!()
347 }
348 #[hax_lib::opaque]
350 pub fn _mm256_castsi256_ps(_: __m256i) -> __m256 {
351 unimplemented!()
352 }
353 #[hax_lib::opaque]
355 pub fn _mm256_castps_si256(_: __m256) -> __m256i {
356 unimplemented!()
357 }
358 #[hax_lib::opaque]
360 pub fn _mm256_movemask_ps(_: __m256) -> i32 {
361 unimplemented!()
362 }
363
364 #[hax_lib::opaque]
366 pub fn _mm256_setzero_si256() -> __m256i {
367 BitVec::from_fn(|_| Bit::Zero)
368 }
369
370 #[hax_lib::opaque]
372 pub fn _mm256_set_m128i(hi: __m128i, lo: __m128i) -> __m256i {
373 BitVec::from_fn(|i| if i < 128 { lo[i] } else { hi[i - 128] })
374 }
375
376 pub use super::*;
377 pub fn _mm256_castsi256_si128(vector: __m256i) -> __m128i {
378 BitVec::from_fn(|i| vector[i])
379 }
380
381 #[hax_lib::opaque]
384 pub fn _mm256_set1_epi32(_: i32) -> __m256i {
385 unimplemented!()
386 }
387
388 #[hax_lib::opaque]
391 pub fn _mm256_set_epi32(
392 _e0: i32,
393 _e1: i32,
394 _e2: i32,
395 _e3: i32,
396 _e4: i32,
397 _e5: i32,
398 _e6: i32,
399 _e7: i32,
400 ) -> __m256i {
401 todo!()
402 }
403
404 #[hax_lib::opaque]
407 pub fn _mm256_set_epi16(
408 _e00: i16,
409 _e01: i16,
410 _e02: i16,
411 _e03: i16,
412 _e04: i16,
413 _e05: i16,
414 _e06: i16,
415 _e07: i16,
416 _e08: i16,
417 _e09: i16,
418 _e10: i16,
419 _e11: i16,
420 _e12: i16,
421 _e13: i16,
422 _e14: i16,
423 _e15: i16,
424 ) -> __m256i {
425 todo!()
426 }
427
428 #[hax_lib::opaque]
431 pub fn _mm256_set_epi8(
432 _e00: i8,
433 _e01: i8,
434 _e02: i8,
435 _e03: i8,
436 _e04: i8,
437 _e05: i8,
438 _e06: i8,
439 _e07: i8,
440 _e08: i8,
441 _e09: i8,
442 _e10: i8,
443 _e11: i8,
444 _e12: i8,
445 _e13: i8,
446 _e14: i8,
447 _e15: i8,
448 _e16: i8,
449 _e17: i8,
450 _e18: i8,
451 _e19: i8,
452 _e20: i8,
453 _e21: i8,
454 _e22: i8,
455 _e23: i8,
456 _e24: i8,
457 _e25: i8,
458 _e26: i8,
459 _e27: i8,
460 _e28: i8,
461 _e29: i8,
462 _e30: i8,
463 _e31: i8,
464 ) -> __m256i {
465 todo!()
466 }
467 #[hax_lib::opaque]
469 pub fn _mm256_set1_epi16(_: i16) -> __m256i {
470 unimplemented!()
471 }
472}
473pub use avx2::*;
474pub mod avx2 {
475 use super::*;
476
477 #[hax_lib::opaque]
479 pub fn _mm256_blend_epi32<const IMM8: i32>(_: __m256i, _: __m256i) -> __m256i {
480 unimplemented!()
481 }
482 #[hax_lib::opaque]
484 pub fn _mm256_shuffle_epi32<const MASK: i32>(_: __m256i) -> __m256i {
485 unimplemented!()
486 }
487 #[hax_lib::opaque]
489 pub fn _mm256_sub_epi32(_: __m256i, _: __m256i) -> __m256i {
490 unimplemented!()
491 }
492 #[hax_lib::opaque]
494 pub fn _mm256_mul_epi32(_: __m256i, _: __m256i) -> __m256i {
495 unimplemented!()
496 }
497
498 #[hax_lib::opaque]
500 pub fn _mm256_add_epi16(_: __m256i, _: __m256i) -> __m256i {
501 unimplemented!()
502 }
503 #[hax_lib::opaque]
505 pub fn _mm256_madd_epi16(_: __m256i, _: __m256i) -> __m256i {
506 unimplemented!()
507 }
508 #[hax_lib::opaque]
510 pub fn _mm256_add_epi32(_: __m256i, _: __m256i) -> __m256i {
511 unimplemented!()
512 }
513 #[hax_lib::opaque]
515 pub fn _mm256_add_epi64(_: __m256i, _: __m256i) -> __m256i {
516 unimplemented!()
517 }
518 #[hax_lib::opaque]
520 pub fn _mm256_abs_epi32(_: __m256i) -> __m256i {
521 unimplemented!()
522 }
523 #[hax_lib::opaque]
525 pub fn _mm256_sub_epi16(_: __m256i, _: __m256i) -> __m256i {
526 unimplemented!()
527 }
528
529 #[hax_lib::opaque]
531 pub fn _mm256_cmpgt_epi16(_: __m256i, _: __m256i) -> __m256i {
532 unimplemented!()
533 }
534 #[hax_lib::opaque]
536 pub fn _mm256_cmpgt_epi32(_: __m256i, _: __m256i) -> __m256i {
537 unimplemented!()
538 }
539 #[hax_lib::opaque]
541 pub fn _mm256_cmpeq_epi32(_: __m256i, _: __m256i) -> __m256i {
542 unimplemented!()
543 }
544 #[hax_lib::opaque]
546 pub fn _mm256_sign_epi32(_: __m256i, _: __m256i) -> __m256i {
547 unimplemented!()
548 }
549
550 #[hax_lib::opaque]
552 pub fn _mm256_mullo_epi32(_: __m256i, _: __m256i) -> __m256i {
553 unimplemented!()
554 }
555 #[hax_lib::opaque]
557 pub fn _mm256_mulhi_epi16(_: __m256i, _: __m256i) -> __m256i {
558 unimplemented!()
559 }
560 #[hax_lib::opaque]
562 pub fn _mm256_mul_epu32(_: __m256i, _: __m256i) -> __m256i {
563 unimplemented!()
564 }
565 #[hax_lib::opaque]
567 pub fn _mm256_and_si256(_: __m256i, _: __m256i) -> __m256i {
568 unimplemented!()
569 }
570 #[hax_lib::opaque]
572 pub fn _mm256_or_si256(_: __m256i, _: __m256i) -> __m256i {
573 unimplemented!()
574 }
575
576 #[hax_lib::opaque]
578 pub fn _mm256_xor_si256(_: __m256i, _: __m256i) -> __m256i {
579 unimplemented!()
580 }
581 #[hax_lib::opaque]
583 pub fn _mm256_srai_epi16<const IMM8: i32>(_: __m256i) -> __m256i {
584 unimplemented!()
585 }
586 #[hax_lib::opaque]
588 pub fn _mm256_srai_epi32<const IMM8: i32>(_: __m256i) -> __m256i {
589 unimplemented!()
590 }
591 #[hax_lib::opaque]
593 pub fn _mm256_srli_epi16<const IMM8: i32>(_: __m256i) -> __m256i {
594 unimplemented!()
595 }
596 #[hax_lib::opaque]
598 pub fn _mm256_srli_epi32<const IMM8: i32>(_: __m256i) -> __m256i {
599 unimplemented!()
600 }
601
602 #[hax_lib::opaque]
604 pub fn _mm256_slli_epi32<const IMM8: i32>(_: __m256i) -> __m256i {
605 unimplemented!()
606 }
607 #[hax_lib::opaque]
609 pub fn _mm256_permute4x64_epi64<const IMM8: i32>(_: __m256i) -> __m256i {
610 unimplemented!()
611 }
612 #[hax_lib::opaque]
614 pub fn _mm256_unpackhi_epi64(_: __m256i, _: __m256i) -> __m256i {
615 unimplemented!()
616 }
617 #[hax_lib::opaque]
619 pub fn _mm256_unpacklo_epi32(_: __m256i, _: __m256i) -> __m256i {
620 unimplemented!()
621 }
622 #[hax_lib::opaque]
624 pub fn _mm256_unpackhi_epi32(_: __m256i, _: __m256i) -> __m256i {
625 unimplemented!()
626 }
627
628 #[hax_lib::opaque]
630 pub fn _mm256_cvtepi16_epi32(_: __m128i) -> __m256i {
631 unimplemented!()
632 }
633
634 #[hax_lib::opaque]
636 pub fn _mm256_packs_epi32(_: __m256i, _: __m256i) -> __m256i {
637 unimplemented!()
638 }
639 #[hax_lib::opaque]
641 pub fn _mm256_inserti128_si256<const IMM8: i32>(_: __m256i, _: __m128i) -> __m256i {
642 unimplemented!()
643 }
644 #[hax_lib::opaque]
646 pub fn _mm256_blend_epi16<const IMM8: i32>(_: __m256i, _: __m256i) -> __m256i {
647 unimplemented!()
648 }
649
650 #[hax_lib::opaque]
652 pub fn _mm256_srlv_epi64(_: __m256i, _: __m256i) -> __m256i {
653 unimplemented!()
654 }
655 #[hax_lib::opaque]
657 pub fn _mm_sllv_epi32(_: __m128i, _: __m128i) -> __m128i {
658 unimplemented!()
659 }
660 #[hax_lib::opaque]
662 pub fn _mm256_slli_epi64<const IMM8: i32>(_: __m256i) -> __m256i {
663 unimplemented!()
664 }
665
666 #[hax_lib::opaque]
671 pub fn _mm256_bsrli_epi128<const IMM8: i32>(_: __m256i) -> __m256i {
672 unimplemented!()
673 }
674 #[hax_lib::opaque]
676 pub fn _mm256_andnot_si256(_: __m256i, _: __m256i) -> __m256i {
677 unimplemented!()
678 }
679
680 #[hax_lib::opaque]
682 pub fn _mm256_unpacklo_epi64(_: __m256i, _: __m256i) -> __m256i {
683 unimplemented!()
684 }
685 #[hax_lib::opaque]
687 pub fn _mm256_permute2x128_si256<const IMM8: i32>(_: __m256i, _: __m256i) -> __m256i {
688 unimplemented!()
689 }
690
691 #[hax_lib::exclude]
693 pub fn _mm_storeu_si128(output: *mut __m128i, a: __m128i) {
694 let mut out = [0u8; 128];
696 extra::mm_storeu_bytes_si128(&mut out, a);
697 unsafe {
698 *(output.as_mut().unwrap()) = BitVec::from_slice(&out, 8);
699 }
700 }
701 pub fn _mm256_slli_epi16<const SHIFT_BY: i32>(vector: __m256i) -> __m256i {
703 vector.chunked_shift::<16, 16>(FunArray::from_fn(|_| SHIFT_BY as i128))
704 }
705 pub fn _mm256_srli_epi64<const SHIFT_BY: i32>(vector: __m256i) -> __m256i {
707 vector.chunked_shift::<64, 4>(FunArray::from_fn(|_| -(SHIFT_BY as i128)))
708 }
709 #[hax_lib::opaque]
711 pub fn _mm256_mullo_epi16(_vector: __m256i, _shifts: __m256i) -> __m256i {
712 todo!()
713 }
714 #[hax_lib::opaque]
716 pub fn _mm256_sllv_epi32(vector: __m256i, counts: __m256i) -> __m256i {
717 extra::mm256_sllv_epi32_u32_array(vector, counts.to_vec().try_into().unwrap())
718 }
719 #[hax_lib::opaque]
721 pub fn _mm256_srlv_epi32(vector: __m256i, counts: __m256i) -> __m256i {
722 extra::mm256_srlv_epi32_u32_array(vector, counts.to_vec().try_into().unwrap())
723 }
724 #[hax_lib::opaque]
726 pub fn _mm256_permutevar8x32_epi32(a: __m256i, b: __m256i) -> __m256i {
727 extra::mm256_permutevar8x32_epi32_u32_array(a, b.to_vec().try_into().unwrap())
728 }
729 pub fn _mm256_extracti128_si256<const IMM8: i32>(vector: __m256i) -> __m128i {
731 BitVec::from_fn(|i| vector[i + if IMM8 == 0 { 0 } else { 128 }])
732 }
733 #[hax_lib::opaque]
735 pub fn _mm256_shuffle_epi8(vector: __m256i, indexes: __m256i) -> __m256i {
736 let indexes = indexes.to_vec().try_into().unwrap();
737 extra::mm256_shuffle_epi8_i8_array(vector, indexes)
738 }
739}
740
741pub use other::*;
742pub mod other {
743 use super::*;
744
745 #[hax_lib::opaque]
747 pub fn _mm_aeskeygenassist_si128(_: __m128i, _: i32) -> __m128i {
748 unimplemented!()
749 }
750
751 #[hax_lib::opaque]
753 pub fn _mm_aesenclast_si128(_: __m128i, _: __m128i) -> __m128i {
754 unimplemented!()
755 }
756
757 #[hax_lib::opaque]
759 pub fn _mm_aesenc_si128(_: __m128i, _: __m128i) -> __m128i {
760 unimplemented!()
761 }
762
763 #[hax_lib::opaque]
765 pub fn _mm_clmulepi64_si128(_: __m128i, _: __m128i, _: i32) -> __m128i {
766 unimplemented!()
767 }
768}
769const _: () = {
771 #[hax_lib::fstar::before("[@@ $REWRITE_RULE ]")]
772 #[hax_lib::lemma]
773 #[hax_lib::opaque]
774 fn _rw_mm256_sllv_epi32(
775 vector: __m256i,
776 b7: i32,
777 b6: i32,
778 b5: i32,
779 b4: i32,
780 b3: i32,
781 b2: i32,
782 b1: i32,
783 b0: i32,
784 ) -> Proof<
785 {
786 hax_lib::prop::eq(
787 _mm256_sllv_epi32(vector, _mm256_set_epi32(b7, b6, b5, b4, b3, b2, b1, b0)),
788 extra::mm256_sllv_epi32_u32(
789 vector, b7 as u32, b6 as u32, b5 as u32, b4 as u32, b3 as u32, b2 as u32,
790 b1 as u32, b0 as u32,
791 ),
792 )
793 },
794 > {
795 }
796
797 #[hax_lib::fstar::before("[@@ $REWRITE_RULE ]")]
798 #[hax_lib::lemma]
799 #[hax_lib::opaque]
800 fn _rw_mm256_srlv_epi32(
801 vector: __m256i,
802 b7: i32,
803 b6: i32,
804 b5: i32,
805 b4: i32,
806 b3: i32,
807 b2: i32,
808 b1: i32,
809 b0: i32,
810 ) -> Proof<
811 {
812 hax_lib::prop::eq(
813 _mm256_srlv_epi32(vector, _mm256_set_epi32(b7, b6, b5, b4, b3, b2, b1, b0)),
814 extra::mm256_srlv_epi32_u32(
815 vector, b7 as u32, b6 as u32, b5 as u32, b4 as u32, b3 as u32, b2 as u32,
816 b1 as u32, b0 as u32,
817 ),
818 )
819 },
820 > {
821 }
822
823 #[hax_lib::fstar::before("[@@ $REWRITE_RULE ]")]
824 #[hax_lib::lemma]
825 #[hax_lib::opaque]
826 fn _rw_mm256_permutevar8x32_epi32(
827 vector: __m256i,
828 b7: i32,
829 b6: i32,
830 b5: i32,
831 b4: i32,
832 b3: i32,
833 b2: i32,
834 b1: i32,
835 b0: i32,
836 ) -> Proof<
837 {
838 hax_lib::prop::eq(
839 _mm256_permutevar8x32_epi32(
840 vector,
841 _mm256_set_epi32(b7, b6, b5, b4, b3, b2, b1, b0),
842 ),
843 extra::mm256_permutevar8x32_epi32_u32(
844 vector, b7 as u32, b6 as u32, b5 as u32, b4 as u32, b3 as u32, b2 as u32,
845 b1 as u32, b0 as u32,
846 ),
847 )
848 },
849 > {
850 }
851
852 #[hax_lib::fstar::replace(
853 r#"
854[@@ Core_models.Abstractions.Bitvec.v_REWRITE_RULE ]
855
856assume
857val e___e_rw_mm256_mullo_epi16_shifts':
858 vector: $:{__m256i} ->
859 s15: (n: $:{u8} {v n < 16}) ->
860 s14: (n: $:{u8} {v n < 16}) ->
861 s13: (n: $:{u8} {v n < 16}) ->
862 s12: (n: $:{u8} {v n < 16}) ->
863 s11: (n: $:{u8} {v n < 16}) ->
864 s10: (n: $:{u8} {v n < 16}) ->
865 s9: (n: $:{u8} {v n < 16}) ->
866 s8: (n: $:{u8} {v n < 16}) ->
867 s7: (n: $:{u8} {v n < 16}) ->
868 s6: (n: $:{u8} {v n < 16}) ->
869 s5: (n: $:{u8} {v n < 16}) ->
870 s4: (n: $:{u8} {v n < 16}) ->
871 s3: (n: $:{u8} {v n < 16}) ->
872 s2: (n: $:{u8} {v n < 16}) ->
873 s1: (n: $:{u8} {v n < 16}) ->
874 s0: (n: $:{u8} {v n < 16})
875 -> Lemma
876 (ensures
877 ($_mm256_mullo_epi16 vector
878 ($_mm256_set_epi16 (${1i16} <<! s15 <: i16)
879 (${1i16} <<! s14 <: i16) (${1i16} <<! s13 <: i16) (${1i16} <<! s12 <: i16)
880 (${1i16} <<! s11 <: i16) (${1i16} <<! s10 <: i16) (${1i16} <<! s9 <: i16)
881 (${1i16} <<! s8 <: i16) (${1i16} <<! s7 <: i16) (${1i16} <<! s6 <: i16)
882 (${1i16} <<! s5 <: i16) (${1i16} <<! s4 <: i16) (${1i16} <<! s3 <: i16)
883 (${1i16} <<! s2 <: i16) (${1i16} <<! s1 <: i16) (${1i16} <<! s0 <: i16)
884 )
885 ) ==
886 (${extra::mm256_mullo_epi16_shifts} vector s15 s14 s13 s12 s11 s10 s9 s8 s7
887 s6 s5 s4 s3 s2 s1 s0))
888
889let ${_rw_mm256_mullo_epi16_shifts} = e___e_rw_mm256_mullo_epi16_shifts'
890 "#
891 )]
892 pub fn _rw_mm256_mullo_epi16_shifts() {}
894
895 #[hax_lib::fstar::before("[@@ $REWRITE_RULE ]")]
896 #[hax_lib::lemma]
897 #[hax_lib::opaque]
898 #[allow(unused_variables)]
899 fn _rw_mm_shuffle_epi8(
900 vector: __m128i,
901 e15: i8,
902 e14: i8,
903 e13: i8,
904 e12: i8,
905 e11: i8,
906 e10: i8,
907 e9: i8,
908 e8: i8,
909 e7: i8,
910 e6: i8,
911 e5: i8,
912 e4: i8,
913 e3: i8,
914 e2: i8,
915 e1: i8,
916 e0: i8,
917 ) -> Proof<
918 {
919 hax_lib::prop::eq(
920 _mm_shuffle_epi8(
921 vector,
922 _mm_set_epi8(
923 e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2, e1, e0,
924 ),
925 ),
926 extra::mm_shuffle_epi8_u8(
927 vector, e15 as u8, e14 as u8, e13 as u8, e12 as u8, e11 as u8, e10 as u8,
928 e9 as u8, e8 as u8, e7 as u8, e6 as u8, e5 as u8, e4 as u8, e3 as u8, e2 as u8,
929 e1 as u8, e0 as u8,
930 ),
931 )
932 },
933 > {
934 }
935
936 #[hax_lib::fstar::before("[@@ $REWRITE_RULE ]")]
937 #[hax_lib::lemma]
938 #[hax_lib::opaque]
939 #[allow(unused_variables)]
940 fn _rw_mm256_shuffle_epi8(
941 vector: __m256i,
942 byte31: i8,
943 byte30: i8,
944 byte29: i8,
945 byte28: i8,
946 byte27: i8,
947 byte26: i8,
948 byte25: i8,
949 byte24: i8,
950 byte23: i8,
951 byte22: i8,
952 byte21: i8,
953 byte20: i8,
954 byte19: i8,
955 byte18: i8,
956 byte17: i8,
957 byte16: i8,
958 byte15: i8,
959 byte14: i8,
960 byte13: i8,
961 byte12: i8,
962 byte11: i8,
963 byte10: i8,
964 byte9: i8,
965 byte8: i8,
966 byte7: i8,
967 byte6: i8,
968 byte5: i8,
969 byte4: i8,
970 byte3: i8,
971 byte2: i8,
972 byte1: i8,
973 byte0: i8,
974 ) -> Proof<
975 {
976 hax_lib::prop::eq(
977 _mm256_shuffle_epi8(
978 vector,
979 _mm256_set_epi8(
980 byte31, byte30, byte29, byte28, byte27, byte26, byte25, byte24, byte23,
981 byte22, byte21, byte20, byte19, byte18, byte17, byte16, byte15, byte14,
982 byte13, byte12, byte11, byte10, byte9, byte8, byte7, byte6, byte5, byte4,
983 byte3, byte2, byte1, byte0,
984 ),
985 ),
986 extra::mm256_shuffle_epi8_i8(
987 vector, byte31, byte30, byte29, byte28, byte27, byte26, byte25, byte24, byte23,
988 byte22, byte21, byte20, byte19, byte18, byte17, byte16, byte15, byte14, byte13,
989 byte12, byte11, byte10, byte9, byte8, byte7, byte6, byte5, byte4, byte3, byte2,
990 byte1, byte0,
991 ),
992 )
993 },
994 > {
995 }
996};
997
998pub mod extra {
999 use super::*;
1000
1001 pub fn mm256_sllv_epi32_u32_array(
1002 vector: BitVec<256>,
1003 counts: FunArray<8, u32>,
1004 ) -> BitVec<256> {
1005 vector.chunked_shift::<32, 8>(FunArray::from_fn(|i| counts[i] as i128))
1006 }
1007
1008 pub fn mm256_sllv_epi32_u32(
1009 vector: BitVec<256>,
1010 b7: u32,
1011 b6: u32,
1012 b5: u32,
1013 b4: u32,
1014 b3: u32,
1015 b2: u32,
1016 b1: u32,
1017 b0: u32,
1018 ) -> BitVec<256> {
1019 mm256_sllv_epi32_u32_array(
1020 vector,
1021 FunArray::from_fn(|i| match i {
1022 7 => b7,
1023 6 => b6,
1024 5 => b5,
1025 4 => b4,
1026 3 => b3,
1027 2 => b2,
1028 1 => b1,
1029 0 => b0,
1030 _ => unreachable!(),
1031 }),
1032 )
1033 }
1034
1035 pub fn mm256_srlv_epi32_u32_array(
1036 vector: BitVec<256>,
1037 counts: FunArray<8, u32>,
1038 ) -> BitVec<256> {
1039 vector.chunked_shift::<32, 8>(FunArray::from_fn(|i| -(counts[i] as i128)))
1040 }
1041
1042 pub fn mm256_srlv_epi32_u32(
1043 vector: BitVec<256>,
1044 b7: u32,
1045 b6: u32,
1046 b5: u32,
1047 b4: u32,
1048 b3: u32,
1049 b2: u32,
1050 b1: u32,
1051 b0: u32,
1052 ) -> BitVec<256> {
1053 mm256_srlv_epi32_u32_array(
1054 vector,
1055 FunArray::from_fn(|i| match i {
1056 7 => b7,
1057 6 => b6,
1058 5 => b5,
1059 4 => b4,
1060 3 => b3,
1061 2 => b2,
1062 1 => b1,
1063 0 => b0,
1064 _ => unreachable!(),
1065 }),
1066 )
1067 }
1068
1069 pub fn mm256_permutevar8x32_epi32_u32_array(
1070 a: BitVec<256>,
1071 b: FunArray<8, u32>,
1072 ) -> BitVec<256> {
1073 BitVec::from_fn(|i| {
1074 let j = i / 32;
1075 let index = ((b[j] % 8) as u64) * 32;
1076 a[index + i % 32]
1077 })
1078 }
1079
1080 pub fn mm256_permutevar8x32_epi32_u32(
1081 vector: BitVec<256>,
1082 b7: u32,
1083 b6: u32,
1084 b5: u32,
1085 b4: u32,
1086 b3: u32,
1087 b2: u32,
1088 b1: u32,
1089 b0: u32,
1090 ) -> BitVec<256> {
1091 mm256_permutevar8x32_epi32_u32_array(
1092 vector,
1093 FunArray::from_fn(|i| match i {
1094 7 => b7,
1095 6 => b6,
1096 5 => b5,
1097 4 => b4,
1098 3 => b3,
1099 2 => b2,
1100 1 => b1,
1101 0 => b0,
1102 _ => unreachable!(),
1103 }),
1104 )
1105 }
1106
1107 pub fn mm_shuffle_epi8_u8_array(vector: BitVec<128>, indexes: FunArray<16, u8>) -> BitVec<128> {
1108 BitVec::from_fn(|i| {
1109 let nth = i / 8;
1110 let index = indexes[nth];
1111 if index > 127 {
1112 Bit::Zero
1113 } else {
1114 let index = (index % 16) as u64;
1115 vector[index * 8 + i % 8]
1116 }
1117 })
1118 }
1119
1120 pub fn mm_shuffle_epi8_u8(
1121 vector: BitVec<128>,
1122 b15: u8,
1123 b14: u8,
1124 b13: u8,
1125 b12: u8,
1126 b11: u8,
1127 b10: u8,
1128 b9: u8,
1129 b8: u8,
1130 b7: u8,
1131 b6: u8,
1132 b5: u8,
1133 b4: u8,
1134 b3: u8,
1135 b2: u8,
1136 b1: u8,
1137 b0: u8,
1138 ) -> BitVec<128> {
1139 let indexes = FunArray::from_fn(|i| match i {
1140 15 => b15,
1141 14 => b14,
1142 13 => b13,
1143 12 => b12,
1144 11 => b11,
1145 10 => b10,
1146 9 => b9,
1147 8 => b8,
1148 7 => b7,
1149 6 => b6,
1150 5 => b5,
1151 4 => b4,
1152 3 => b3,
1153 2 => b2,
1154 1 => b1,
1155 0 => b0,
1156 _ => unreachable!(),
1157 });
1158 mm_shuffle_epi8_u8_array(vector, indexes)
1159 }
1160
1161 pub fn mm256_shuffle_epi8_i8_array(
1162 vector: BitVec<256>,
1163 indexes: FunArray<32, i8>,
1164 ) -> BitVec<256> {
1165 BitVec::from_fn(|i| {
1166 let nth = i / 8;
1167 let index = indexes[nth];
1168 if index < 0 {
1169 Bit::Zero
1170 } else {
1171 let index = (index % 16) as u64;
1172 vector[if i < 128 { 0 } else { 128 } + index * 8 + i % 8]
1173 }
1174 })
1175 }
1176
1177 pub fn mm256_shuffle_epi8_i8(
1178 vector: BitVec<256>,
1179 byte31: i8,
1180 byte30: i8,
1181 byte29: i8,
1182 byte28: i8,
1183 byte27: i8,
1184 byte26: i8,
1185 byte25: i8,
1186 byte24: i8,
1187 byte23: i8,
1188 byte22: i8,
1189 byte21: i8,
1190 byte20: i8,
1191 byte19: i8,
1192 byte18: i8,
1193 byte17: i8,
1194 byte16: i8,
1195 byte15: i8,
1196 byte14: i8,
1197 byte13: i8,
1198 byte12: i8,
1199 byte11: i8,
1200 byte10: i8,
1201 byte9: i8,
1202 byte8: i8,
1203 byte7: i8,
1204 byte6: i8,
1205 byte5: i8,
1206 byte4: i8,
1207 byte3: i8,
1208 byte2: i8,
1209 byte1: i8,
1210 byte0: i8,
1211 ) -> BitVec<256> {
1212 let indexes = FunArray::from_fn(|i| match i {
1213 31 => byte31,
1214 30 => byte30,
1215 29 => byte29,
1216 28 => byte28,
1217 27 => byte27,
1218 26 => byte26,
1219 25 => byte25,
1220 24 => byte24,
1221 23 => byte23,
1222 22 => byte22,
1223 21 => byte21,
1224 20 => byte20,
1225 19 => byte19,
1226 18 => byte18,
1227 17 => byte17,
1228 16 => byte16,
1229 15 => byte15,
1230 14 => byte14,
1231 13 => byte13,
1232 12 => byte12,
1233 11 => byte11,
1234 10 => byte10,
1235 9 => byte9,
1236 8 => byte8,
1237 7 => byte7,
1238 6 => byte6,
1239 5 => byte5,
1240 4 => byte4,
1241 3 => byte3,
1242 2 => byte2,
1243 1 => byte1,
1244 0 => byte0,
1245 _ => unreachable!(),
1246 });
1247 mm256_shuffle_epi8_i8_array(vector, indexes)
1248 }
1249
1250 pub fn mm256_mullo_epi16_shifts(
1251 vector: __m256i,
1252 s15: u8,
1253 s14: u8,
1254 s13: u8,
1255 s12: u8,
1256 s11: u8,
1257 s10: u8,
1258 s9: u8,
1259 s8: u8,
1260 s7: u8,
1261 s6: u8,
1262 s5: u8,
1263 s4: u8,
1264 s3: u8,
1265 s2: u8,
1266 s1: u8,
1267 s0: u8,
1268 ) -> __m256i {
1269 let shifts = FunArray::<16, _>::from_fn(|i| match i {
1270 15 => s15,
1271 14 => s14,
1272 13 => s13,
1273 12 => s12,
1274 11 => s11,
1275 10 => s10,
1276 9 => s9,
1277 8 => s8,
1278 7 => s7,
1279 6 => s6,
1280 5 => s5,
1281 4 => s4,
1282 3 => s3,
1283 2 => s2,
1284 1 => s1,
1285 0 => s0,
1286 _ => unreachable!(),
1287 });
1288 mm256_mullo_epi16_shifts_array(vector, shifts)
1289 }
1290 pub fn mm256_mullo_epi16_shifts_array(vector: __m256i, shifts: FunArray<16, u8>) -> __m256i {
1291 BitVec::from_fn(|i| {
1292 let nth_bit = i % 16;
1293 let nth_i16 = i / 16;
1294
1295 let shift = shifts[nth_i16] as u64;
1296
1297 if nth_bit >= shift {
1298 vector[nth_i16 * 16 + nth_bit - shift]
1299 } else {
1300 Bit::Zero
1301 }
1302 })
1303 }
1304
1305 #[hax_lib::exclude]
1306 pub fn mm_storeu_bytes_si128(output: &mut [u8], vector: BitVec<128>) {
1307 output.copy_from_slice(&vector.to_vec()[..]);
1308 }
1309}
1310
1311#[cfg(all(test, any(target_arch = "x86", target_arch = "x86_64")))]
1313mod tests {
1314 use super::*;
1315
1316 const N: usize = 1000;
1318
1319 #[test]
1320 fn mm256_slli_epi16() {
1321 macro_rules! mk {
1322 ($($shift: literal)*) => {
1323 $(for _ in 0..N {
1324 let input = BitVec::<256>::rand();
1325 assert_eq!(
1326 super::_mm256_slli_epi16::<$shift>(input),
1327 unsafe {upstream::_mm256_slli_epi16::<$shift>(input.into()).into()}
1328 );
1329 })*
1330 };
1331 }
1332 mk!(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15);
1333 }
1334
1335 #[test]
1336 fn mm256_srli_epi64() {
1337 macro_rules! mk {
1338 ($($shift: literal)*) => {
1339 $(for _ in 0..N {
1340 let input = BitVec::<256>::rand();
1341 assert_eq!(
1342 super::_mm256_srli_epi64::<$shift>(input),
1343 unsafe{upstream::_mm256_srli_epi64::<$shift>(input.into()).into()}
1344 );
1345 })*
1346 };
1347 }
1348 mk!(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63);
1349 }
1350
1351 #[test]
1352 fn mm256_sllv_epi32() {
1353 for _ in 0..N {
1354 let vector: BitVec<256> = BitVec::rand();
1355 let counts: BitVec<256> = BitVec::rand();
1356 assert_eq!(super::_mm256_sllv_epi32(vector, counts), unsafe {
1357 upstream::_mm256_sllv_epi32(vector.into(), counts.into()).into()
1358 });
1359 }
1360 }
1361
1362 #[test]
1363 fn mm256_srlv_epi32() {
1364 for _ in 0..N {
1365 let vector: BitVec<256> = BitVec::rand();
1366 let counts: BitVec<256> = BitVec::rand();
1367 assert_eq!(super::_mm256_srlv_epi32(vector, counts), unsafe {
1368 upstream::_mm256_srlv_epi32(vector.into(), counts.into()).into()
1369 });
1370 }
1371 }
1372
1373 #[test]
1374 fn mm256_permutevar8x32_epi32() {
1375 for _ in 0..N {
1376 let vector: BitVec<256> = BitVec::rand();
1377 let counts: BitVec<256> = BitVec::rand();
1378 assert_eq!(super::_mm256_permutevar8x32_epi32(vector, counts), unsafe {
1379 upstream::_mm256_permutevar8x32_epi32(vector.into(), counts.into()).into()
1380 });
1381 }
1382 }
1383
1384 #[test]
1385 fn mm256_castsi256_si128() {
1386 for _ in 0..N {
1387 let vector: BitVec<256> = BitVec::rand();
1388 assert_eq!(super::_mm256_castsi256_si128(vector), unsafe {
1389 upstream::_mm256_castsi256_si128(vector.into()).into()
1390 });
1391 }
1392 }
1393
1394 #[test]
1395 fn mm256_extracti128_si256() {
1396 for _ in 0..N {
1397 let vector: BitVec<256> = BitVec::rand();
1398 assert_eq!(super::_mm256_extracti128_si256::<0>(vector), unsafe {
1399 upstream::_mm256_extracti128_si256::<0>(vector.into()).into()
1400 });
1401 assert_eq!(super::_mm256_extracti128_si256::<1>(vector), unsafe {
1402 upstream::_mm256_extracti128_si256::<1>(vector.into()).into()
1403 });
1404 }
1405 }
1406
1407 #[test]
1408 fn mm_shuffle_epi8() {
1409 for _ in 0..N {
1410 let a: BitVec<128> = BitVec::rand();
1411 let b: BitVec<128> = BitVec::rand();
1412
1413 assert_eq!(super::_mm_shuffle_epi8(a, b), unsafe {
1414 upstream::_mm_shuffle_epi8(a.into(), b.into()).into()
1415 });
1416 }
1417 }
1418
1419 #[test]
1420 fn mm256_shuffle_epi8() {
1421 for _ in 0..N {
1422 let a: BitVec<256> = BitVec::rand();
1423 let b: BitVec<256> = BitVec::rand();
1424
1425 assert_eq!(super::_mm256_shuffle_epi8(a, b), unsafe {
1426 upstream::_mm256_shuffle_epi8(a.into(), b.into()).into()
1427 });
1428 }
1429 }
1430
1431 #[test]
1432 fn mm256_mullo_epi16_shifts() {
1433 pub fn upsteam_mm256_mullo_epi16_shifts(
1434 vector: upstream::__m256i,
1435 s15: u8,
1436 s14: u8,
1437 s13: u8,
1438 s12: u8,
1439 s11: u8,
1440 s10: u8,
1441 s9: u8,
1442 s8: u8,
1443 s7: u8,
1444 s6: u8,
1445 s5: u8,
1446 s4: u8,
1447 s3: u8,
1448 s2: u8,
1449 s1: u8,
1450 s0: u8,
1451 ) -> upstream::__m256i {
1452 unsafe {
1453 upstream::_mm256_mullo_epi16(
1454 vector,
1455 upstream::_mm256_set_epi16(
1456 1i16 << s15,
1457 1i16 << s14,
1458 1i16 << s13,
1459 1i16 << s12,
1460 1i16 << s11,
1461 1i16 << s10,
1462 1i16 << s9,
1463 1i16 << s8,
1464 1i16 << s7,
1465 1i16 << s6,
1466 1i16 << s5,
1467 1i16 << s4,
1468 1i16 << s3,
1469 1i16 << s2,
1470 1i16 << s1,
1471 1i16 << s0,
1472 ),
1473 )
1474 }
1475 }
1476 for _ in 0..N {
1477 let a: BitVec<256> = BitVec::rand();
1478 let s15: u8 = rand::random::<u8>() % 16;
1479 let s14: u8 = rand::random::<u8>() % 16;
1480 let s13: u8 = rand::random::<u8>() % 16;
1481 let s12: u8 = rand::random::<u8>() % 16;
1482 let s11: u8 = rand::random::<u8>() % 16;
1483 let s10: u8 = rand::random::<u8>() % 16;
1484 let s9: u8 = rand::random::<u8>() % 16;
1485 let s8: u8 = rand::random::<u8>() % 16;
1486 let s7: u8 = rand::random::<u8>() % 16;
1487 let s6: u8 = rand::random::<u8>() % 16;
1488 let s5: u8 = rand::random::<u8>() % 16;
1489 let s4: u8 = rand::random::<u8>() % 16;
1490 let s3: u8 = rand::random::<u8>() % 16;
1491 let s2: u8 = rand::random::<u8>() % 16;
1492 let s1: u8 = rand::random::<u8>() % 16;
1493 let s0: u8 = rand::random::<u8>() % 16;
1494
1495 assert_eq!(
1496 super::extra::mm256_mullo_epi16_shifts(
1497 a, s15, s14, s13, s12, s11, s10, s9, s8, s7, s6, s5, s4, s3, s2, s1, s0,
1498 ),
1499 upsteam_mm256_mullo_epi16_shifts(
1500 a.into(),
1501 s15,
1502 s14,
1503 s13,
1504 s12,
1505 s11,
1506 s10,
1507 s9,
1508 s8,
1509 s7,
1510 s6,
1511 s5,
1512 s4,
1513 s3,
1514 s2,
1515 s1,
1516 s0,
1517 )
1518 .into()
1519 );
1520 }
1521 }
1522}