2023-07-22 13:32:34 +00:00
#![ feature(
core_intrinsics ,
2023-10-19 21:46:28 +00:00
coroutines ,
2024-04-11 13:15:34 +00:00
stmt_expr_attributes ,
2023-10-19 21:46:28 +00:00
coroutine_trait ,
2023-07-22 13:32:34 +00:00
repr_simd ,
tuple_trait ,
unboxed_closures
) ]
2024-04-23 09:37:28 +00:00
#![ allow(internal_features) ]
2019-02-16 14:42:20 +00:00
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-30 12:37:20 +00:00
use std ::arch ::x86_64 ::* ;
2022-04-22 19:11:38 +00:00
use std ::hint ::black_box ;
2019-02-11 18:40:07 +00:00
use std ::io ::Write ;
2023-10-19 16:06:43 +00:00
use std ::ops ::Coroutine ;
2019-07-27 15:48:24 +00:00
2019-07-24 15:23:23 +00:00
fn main ( ) {
2020-06-20 10:01:24 +00:00
println! ( " {:?} " , std ::env ::args ( ) . collect ::< Vec < _ > > ( ) ) ;
2019-03-30 17:22:43 +00:00
let mutex = std ::sync ::Mutex ::new ( ( ) ) ;
2019-08-12 14:00:10 +00:00
let _guard = mutex . lock ( ) . unwrap ( ) ;
2019-03-30 17:22:43 +00:00
2019-07-24 15:23:23 +00:00
let _ = ::std ::iter ::repeat ( 'a' as u8 ) . take ( 10 ) . collect ::< Vec < _ > > ( ) ;
let stderr = ::std ::io ::stderr ( ) ;
let mut stderr = stderr . lock ( ) ;
2019-10-27 15:55:35 +00:00
std ::thread ::spawn ( move | | {
println! ( " Hello from another thread! " ) ;
} ) ;
2019-07-24 15:23:23 +00:00
writeln! ( stderr , " some {} text " , " <unknown> " ) . unwrap ( ) ;
let _ = std ::process ::Command ::new ( " true " ) . env ( " c " , " d " ) . spawn ( ) ;
println! ( " cargo:rustc-link-lib=z " ) ;
2019-08-12 14:00:10 +00:00
static ONCE : std ::sync ::Once = std ::sync ::Once ::new ( ) ;
2019-07-24 15:23:23 +00:00
ONCE . call_once ( | | { } ) ;
2019-08-12 14:00:10 +00:00
let _eq = LoopState ::Continue ( ( ) ) = = LoopState ::Break ( ( ) ) ;
2019-07-24 15:23:23 +00:00
// Make sure ByValPair values with differently sized components are correctly passed
map ( None ::< ( u8 , Box < Instruction > ) > ) ;
println! ( " {} " , 2.3 f32 . exp ( ) ) ;
println! ( " {} " , 2.3 f32 . exp2 ( ) ) ;
println! ( " {} " , 2.3 f32 . abs ( ) ) ;
println! ( " {} " , 2.3 f32 . sqrt ( ) ) ;
println! ( " {} " , 2.3 f32 . floor ( ) ) ;
println! ( " {} " , 2.3 f32 . ceil ( ) ) ;
println! ( " {} " , 2.3 f32 . min ( 1.0 ) ) ;
println! ( " {} " , 2.3 f32 . max ( 1.0 ) ) ;
2019-07-27 14:51:48 +00:00
println! ( " {} " , 2.3 f32 . powi ( 2 ) ) ;
2019-08-12 13:54:24 +00:00
println! ( " {} " , 2.3 f32 . log2 ( ) ) ;
2019-08-19 13:48:32 +00:00
assert_eq! ( 2.3 f32 . copysign ( - 1.0 ) , - 2.3 f32 ) ;
2019-08-19 15:16:21 +00:00
println! ( " {} " , 2.3 f32 . powf ( 2.0 ) ) ;
2019-07-24 15:23:23 +00:00
2021-04-30 12:49:58 +00:00
assert_eq! ( i64 ::MAX . checked_mul ( 2 ) , None ) ;
2019-08-20 08:40:08 +00:00
assert_eq! ( - 128 i8 , ( - 128 i8 ) . saturating_sub ( 1 ) ) ;
assert_eq! ( 127 i8 , 127 i8 . saturating_sub ( - 128 ) ) ;
assert_eq! ( - 128 i8 , ( - 128 i8 ) . saturating_add ( - 128 ) ) ;
assert_eq! ( 127 i8 , 127 i8 . saturating_add ( 1 ) ) ;
2019-07-24 15:23:23 +00:00
assert_eq! ( 0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000 u128 . leading_zeros ( ) , 26 ) ;
assert_eq! ( 0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000 u128 . trailing_zeros ( ) , 7 ) ;
2023-04-29 12:00:43 +00:00
assert_eq! (
core ::intrinsics ::saturating_sub ( 0 , - 170141183460469231731687303715884105728 i128 ) ,
170141183460469231731687303715884105727 i128
) ;
2019-07-24 15:23:23 +00:00
2023-03-15 14:41:48 +00:00
std ::hint ::black_box ( std ::hint ::black_box ( 7571400400375753350092698930310845914 i128 ) * 10 ) ;
assert! ( 0 i128 . checked_div ( 2 i128 ) . is_some ( ) ) ;
assert! ( 0 u128 . checked_div ( 2 u128 ) . is_some ( ) ) ;
2019-07-24 15:23:23 +00:00
assert_eq! ( 1 u128 + 2 , 3 ) ;
assert_eq! ( 0b100010000000000000000000000000000 u128 > > 10 , 0b10001000000000000000000 u128 ) ;
assert_eq! ( 0xFEDCBA987654321123456789ABCDEF u128 > > 64 , 0xFEDCBA98765432 u128 ) ;
assert_eq! ( 0xFEDCBA987654321123456789ABCDEF u128 as i128 > > 64 , 0xFEDCBA98765432 i128 ) ;
2019-11-16 15:44:26 +00:00
let tmp = 353985398 u128 ;
assert_eq! ( tmp * 932490 u128 , 330087843781020 u128 ) ;
let tmp = - 0x1234_5678_9ABC_DEF0 i64 ;
assert_eq! ( tmp as i128 , - 0x1234_5678_9ABC_DEF0 i128 ) ;
2019-07-27 15:48:24 +00:00
2019-08-21 12:01:29 +00:00
// Check that all u/i128 <-> float casts work correctly.
2019-08-21 12:35:48 +00:00
let houndred_u128 = 100 u128 ;
let houndred_i128 = 100 i128 ;
let houndred_f32 = 100.0 f32 ;
let houndred_f64 = 100.0 f64 ;
assert_eq! ( houndred_u128 as f32 , 100.0 ) ;
assert_eq! ( houndred_u128 as f64 , 100.0 ) ;
assert_eq! ( houndred_f32 as u128 , 100 ) ;
assert_eq! ( houndred_f64 as u128 , 100 ) ;
assert_eq! ( houndred_i128 as f32 , 100.0 ) ;
assert_eq! ( houndred_i128 as f64 , 100.0 ) ;
assert_eq! ( houndred_f32 as i128 , 100 ) ;
assert_eq! ( houndred_f64 as i128 , 100 ) ;
2021-04-30 12:49:58 +00:00
assert_eq! ( 1 u128 . rotate_left ( 2 ) , 4 ) ;
2019-08-21 12:01:29 +00:00
2022-04-22 19:11:38 +00:00
assert_eq! ( black_box ( f32 ::NAN ) as i128 , 0 ) ;
assert_eq! ( black_box ( f32 ::NAN ) as u128 , 0 ) ;
2020-06-20 11:23:31 +00:00
// Test signed 128bit comparing
let max = usize ::MAX as i128 ;
if 100 i128 < 0 i128 | | 100 i128 > max {
panic! ( ) ;
}
2020-06-20 13:15:28 +00:00
test_checked_mul ( ) ;
2019-08-14 13:18:05 +00:00
let _a = 1 u32 < < 2 u8 ;
2019-11-24 14:44:39 +00:00
let empty : [ i32 ; 0 ] = [ ] ;
assert! ( empty . is_sorted ( ) ) ;
2020-03-04 14:04:28 +00:00
println! ( " {:?} " , std ::intrinsics ::caller_location ( ) ) ;
2019-11-09 10:14:18 +00:00
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-27 15:48:24 +00:00
unsafe {
test_simd ( ) ;
}
2020-04-18 13:42:49 +00:00
2024-04-11 13:15:34 +00:00
Box ::pin (
#[ coroutine ]
move | mut _task_context | {
yield ( ) ;
} ,
)
2023-04-29 12:00:43 +00:00
. as_mut ( )
. resume ( 0 ) ;
2020-07-03 14:44:26 +00:00
#[ derive(Copy, Clone) ]
enum Nums {
NegOne = - 1 ,
}
let kind = Nums ::NegOne ;
assert_eq! ( - 1 i128 , kind as i128 ) ;
2020-06-29 09:23:49 +00:00
let options = [ 1 u128 ] ;
match options [ 0 ] {
1 = > ( ) ,
0 = > loop { } ,
v = > panic ( v ) ,
} ;
2022-07-25 14:07:57 +00:00
if black_box ( false ) {
// Based on https://github.com/rust-lang/rust/blob/2f320a224e827b400be25966755a621779f797cc/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
let _ = Foo ::< dyn Send > ::new ( ) ;
#[ allow(dead_code) ]
struct Foo < T : ? Sized > {
base : Never ,
value : T ,
}
impl < T : ? Sized > Foo < T > {
pub fn new ( ) -> Box < Foo < T > > {
todo! ( )
}
}
enum Never { }
}
2023-04-29 12:00:43 +00:00
2024-08-23 08:59:26 +00:00
foo ( I64X2 ( [ 0 , 0 ] ) ) ;
2023-07-22 13:32:34 +00:00
2024-10-03 13:05:23 +00:00
transmute_wide_pointer ( ) ;
2023-07-22 13:32:34 +00:00
rust_call_abi ( ) ;
2024-03-16 17:23:11 +00:00
const fn no_str ( ) -> Option < Box < str > > {
None
}
static STATIC_WITH_MAYBE_NESTED_BOX : & Option < Box < str > > = & no_str ( ) ;
println! ( " {:?} " , STATIC_WITH_MAYBE_NESTED_BOX ) ;
2020-06-29 09:23:49 +00:00
}
fn panic ( _ : u128 ) {
panic! ( ) ;
2019-07-27 15:48:24 +00:00
}
2023-07-22 13:32:34 +00:00
use std ::mem ::transmute ;
#[ cfg(target_pointer_width = " 32 " ) ]
type TwoPtrs = i64 ;
#[ cfg(target_pointer_width = " 64 " ) ]
type TwoPtrs = i128 ;
2024-10-03 13:05:23 +00:00
fn transmute_wide_pointer ( ) -> TwoPtrs {
2023-07-22 13:32:34 +00:00
unsafe { transmute ::< _ , TwoPtrs > ( " true ! " ) }
}
extern " rust-call " fn rust_call_abi_callee < T : std ::marker ::Tuple > ( _ : T ) { }
fn rust_call_abi ( ) {
rust_call_abi_callee ( ( ) ) ;
rust_call_abi_callee ( ( 1 , 2 ) ) ;
}
2023-04-29 12:00:43 +00:00
#[ repr(simd) ]
2024-08-23 08:59:26 +00:00
struct I64X2 ( [ i64 ; 2 ] ) ;
2023-04-29 12:00:43 +00:00
#[ allow(improper_ctypes_definitions) ]
extern " C " fn foo ( _a : I64X2 ) { }
2024-05-13 13:26:33 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " sse4.2 " ) ]
#[ cfg(not(jit)) ]
unsafe fn test_crc32 ( ) {
assert! ( is_x86_feature_detected! ( " sse4.2 " ) ) ;
let a = 42 u32 ;
let b = 0xdeadbeef u64 ;
assert_eq! ( _mm_crc32_u8 ( a , b as u8 ) , 4135334616 ) ;
assert_eq! ( _mm_crc32_u16 ( a , b as u16 ) , 1200687288 ) ;
assert_eq! ( _mm_crc32_u32 ( a , b as u32 ) , 2543798776 ) ;
assert_eq! ( _mm_crc32_u64 ( a as u64 , b as u64 ) , 241952147 ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-27 15:48:24 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_simd ( ) {
2020-08-15 16:55:32 +00:00
assert! ( is_x86_feature_detected! ( " sse2 " ) ) ;
2019-07-27 15:48:24 +00:00
let x = _mm_setzero_si128 ( ) ;
let y = _mm_set1_epi16 ( 7 ) ;
let or = _mm_or_si128 ( x , y ) ;
2019-07-28 07:45:01 +00:00
let cmp_eq = _mm_cmpeq_epi8 ( y , y ) ;
let cmp_lt = _mm_cmplt_epi8 ( y , y ) ;
2019-07-27 15:48:24 +00:00
2022-12-14 18:30:46 +00:00
let ( zero0 , zero1 ) = std ::mem ::transmute ::< _ , ( u64 , u64 ) > ( x ) ;
assert_eq! ( ( zero0 , zero1 ) , ( 0 , 0 ) ) ;
2019-07-27 15:48:24 +00:00
assert_eq! ( std ::mem ::transmute ::< _ , [ u16 ; 8 ] > ( or ) , [ 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ] ) ;
2024-09-22 23:05:04 +00:00
assert_eq! ( std ::mem ::transmute ::< _ , [ u16 ; 8 ] > ( cmp_eq ) , [
0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff
] ) ;
2019-07-28 07:45:01 +00:00
assert_eq! ( std ::mem ::transmute ::< _ , [ u16 ; 8 ] > ( cmp_lt ) , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ;
2019-07-29 09:23:53 +00:00
test_mm_slli_si128 ( ) ;
2019-07-29 10:50:20 +00:00
test_mm_movemask_epi8 ( ) ;
test_mm256_movemask_epi8 ( ) ;
2019-07-30 12:37:20 +00:00
test_mm_add_epi8 ( ) ;
test_mm_add_pd ( ) ;
2019-07-31 07:45:11 +00:00
test_mm_cvtepi8_epi16 ( ) ;
2024-06-30 11:28:14 +00:00
#[ cfg(not(jit)) ]
test_mm_cvtps_epi32 ( ) ;
test_mm_cvttps_epi32 ( ) ;
2019-08-05 14:28:27 +00:00
test_mm_cvtsi128_si64 ( ) ;
2019-07-29 16:59:17 +00:00
2020-08-08 14:32:03 +00:00
test_mm_extract_epi8 ( ) ;
test_mm_insert_epi16 ( ) ;
2023-06-15 17:56:01 +00:00
test_mm_shuffle_epi8 ( ) ;
2024-09-15 17:24:43 +00:00
#[ cfg(not(jit)) ]
test_mm_cmpestri ( ) ;
2023-06-15 17:56:01 +00:00
test_mm256_shuffle_epi8 ( ) ;
test_mm256_permute2x128_si256 ( ) ;
2024-05-13 13:26:33 +00:00
test_mm256_permutevar8x32_epi32 ( ) ;
2019-08-16 14:04:50 +00:00
2023-04-29 12:00:43 +00:00
#[ rustfmt::skip ]
2019-07-29 16:59:17 +00:00
let mask1 = _mm_movemask_epi8 ( dbg! ( _mm_setr_epi8 ( 255 u8 as i8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ) ;
assert_eq! ( mask1 , 1 ) ;
2024-05-13 13:26:33 +00:00
#[ cfg(not(jit)) ]
test_crc32 ( ) ;
2019-07-29 09:23:53 +00:00
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-29 09:23:53 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_mm_slli_si128 ( ) {
#[ rustfmt::skip ]
let a = _mm_setr_epi8 (
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ,
) ;
let r = _mm_slli_si128 ( a , 1 ) ;
let e = _mm_setr_epi8 ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) ;
assert_eq_m128i ( r , e ) ;
#[ rustfmt::skip ]
let a = _mm_setr_epi8 (
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ,
) ;
let r = _mm_slli_si128 ( a , 15 ) ;
let e = _mm_setr_epi8 ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 ) ;
assert_eq_m128i ( r , e ) ;
#[ rustfmt::skip ]
let a = _mm_setr_epi8 (
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ,
) ;
let r = _mm_slli_si128 ( a , 16 ) ;
assert_eq_m128i ( r , _mm_set1_epi8 ( 0 ) ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-29 10:50:20 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_mm_movemask_epi8 ( ) {
#[ rustfmt::skip ]
let a = _mm_setr_epi8 (
0b1000_0000 u8 as i8 , 0b0 , 0b1000_0000 u8 as i8 , 0b01 ,
0b0101 , 0b1111_0000 u8 as i8 , 0 , 0 ,
0 , 0 , 0b1111_0000 u8 as i8 , 0b0101 ,
0b01 , 0b1000_0000 u8 as i8 , 0b0 , 0b1000_0000 u8 as i8 ,
) ;
let r = _mm_movemask_epi8 ( a ) ;
assert_eq! ( r , 0b10100100_00100101 ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-29 10:50:20 +00:00
#[ target_feature(enable = " avx2 " ) ]
unsafe fn test_mm256_movemask_epi8 ( ) {
let a = _mm256_set1_epi8 ( - 1 ) ;
let r = _mm256_movemask_epi8 ( a ) ;
let e = - 1 ;
assert_eq! ( r , e ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-30 12:37:20 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_mm_add_epi8 ( ) {
let a = _mm_setr_epi8 ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) ;
#[ rustfmt::skip ]
let b = _mm_setr_epi8 (
16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 ,
) ;
let r = _mm_add_epi8 ( a , b ) ;
#[ rustfmt::skip ]
let e = _mm_setr_epi8 (
16 , 18 , 20 , 22 , 24 , 26 , 28 , 30 , 32 , 34 , 36 , 38 , 40 , 42 , 44 , 46 ,
) ;
assert_eq_m128i ( r , e ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-30 12:37:20 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_mm_add_pd ( ) {
let a = _mm_setr_pd ( 1.0 , 2.0 ) ;
let b = _mm_setr_pd ( 5.0 , 10.0 ) ;
let r = _mm_add_pd ( a , b ) ;
assert_eq_m128d ( r , _mm_setr_pd ( 6.0 , 12.0 ) ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-29 09:23:53 +00:00
fn assert_eq_m128i ( x : std ::arch ::x86_64 ::__m128i , y : std ::arch ::x86_64 ::__m128i ) {
unsafe {
2019-08-12 14:00:10 +00:00
assert_eq! ( std ::mem ::transmute ::< _ , [ u8 ; 16 ] > ( x ) , std ::mem ::transmute ::< _ , [ u8 ; 16 ] > ( y ) ) ;
2019-07-29 09:23:53 +00:00
}
2019-07-24 15:23:23 +00:00
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-30 12:37:20 +00:00
#[ target_feature(enable = " sse2 " ) ]
pub unsafe fn assert_eq_m128d ( a : __m128d , b : __m128d ) {
if _mm_movemask_pd ( _mm_cmpeq_pd ( a , b ) ) ! = 0b11 {
panic! ( " {:?} != {:?} " , a , b ) ;
}
}
2023-06-15 17:56:01 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " avx " ) ]
pub unsafe fn assert_eq_m256i ( a : __m256i , b : __m256i ) {
assert_eq! ( std ::mem ::transmute ::< _ , [ u64 ; 4 ] > ( a ) , std ::mem ::transmute ::< _ , [ u64 ; 4 ] > ( b ) )
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-08-05 14:28:27 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_mm_cvtsi128_si64 ( ) {
let r = _mm_cvtsi128_si64 ( std ::mem ::transmute ::< [ i64 ; 2 ] , _ > ( [ 5 , 0 ] ) ) ;
assert_eq! ( r , 5 ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-07-31 07:45:11 +00:00
#[ target_feature(enable = " sse4.1 " ) ]
unsafe fn test_mm_cvtepi8_epi16 ( ) {
let a = _mm_set1_epi8 ( 10 ) ;
let r = _mm_cvtepi8_epi16 ( a ) ;
let e = _mm_set1_epi16 ( 10 ) ;
assert_eq_m128i ( r , e ) ;
let a = _mm_set1_epi8 ( - 10 ) ;
let r = _mm_cvtepi8_epi16 ( a ) ;
let e = _mm_set1_epi16 ( - 10 ) ;
assert_eq_m128i ( r , e ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2019-08-16 14:04:50 +00:00
#[ target_feature(enable = " sse4.1 " ) ]
unsafe fn test_mm_extract_epi8 ( ) {
#[ rustfmt::skip ]
let a = _mm_setr_epi8 (
- 1 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
8 , 9 , 10 , 11 , 12 , 13 , 14 , 15
) ;
let r1 = _mm_extract_epi8 ( a , 0 ) ;
2021-05-27 11:08:14 +00:00
let r2 = _mm_extract_epi8 ( a , 3 ) ;
2019-08-16 14:04:50 +00:00
assert_eq! ( r1 , 0xFF ) ;
assert_eq! ( r2 , 3 ) ;
}
2020-08-20 11:22:07 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
2020-07-19 12:54:18 +00:00
#[ target_feature(enable = " sse2 " ) ]
unsafe fn test_mm_insert_epi16 ( ) {
let a = _mm_setr_epi16 ( 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
let r = _mm_insert_epi16 ( a , 9 , 0 ) ;
let e = _mm_setr_epi16 ( 9 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ) ;
assert_eq_m128i ( r , e ) ;
}
2023-06-15 17:56:01 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " ssse3 " ) ]
unsafe fn test_mm_shuffle_epi8 ( ) {
#[ rustfmt::skip ]
let a = _mm_setr_epi8 (
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ,
9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ,
) ;
#[ rustfmt::skip ]
let b = _mm_setr_epi8 (
4 , 128_ u8 as i8 , 4 , 3 ,
24 , 12 , 6 , 19 ,
12 , 5 , 5 , 10 ,
4 , 1 , 8 , 0 ,
) ;
let expected = _mm_setr_epi8 ( 5 , 0 , 5 , 4 , 9 , 13 , 7 , 4 , 13 , 6 , 6 , 11 , 5 , 2 , 9 , 1 ) ;
let r = _mm_shuffle_epi8 ( a , b ) ;
assert_eq_m128i ( r , expected ) ;
}
2024-09-15 17:24:43 +00:00
// Currently one cannot `load` a &[u8] that is less than 16
// in length. This makes loading strings less than 16 in length
// a bit difficult. Rather than `load` and mutate the __m128i,
// it is easier to memcpy the given string to a local slice with
// length 16 and `load` the local slice.
#[ cfg(not(jit)) ]
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " sse4.2 " ) ]
unsafe fn str_to_m128i ( s : & [ u8 ] ) -> __m128i {
assert! ( s . len ( ) < = 16 ) ;
let slice = & mut [ 0 u8 ; 16 ] ;
std ::ptr ::copy_nonoverlapping ( s . as_ptr ( ) , slice . as_mut_ptr ( ) , s . len ( ) ) ;
_mm_loadu_si128 ( slice . as_ptr ( ) as * const _ )
}
#[ cfg(not(jit)) ]
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " sse4.2 " ) ]
unsafe fn test_mm_cmpestri ( ) {
let a = str_to_m128i ( b " bar - garbage " ) ;
let b = str_to_m128i ( b " foobar " ) ;
let i = _mm_cmpestri ::< _SIDD_CMP_EQUAL_ORDERED > ( a , 3 , b , 6 ) ;
assert_eq! ( 3 , i ) ;
}
2023-06-15 17:56:01 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " avx2 " ) ]
unsafe fn test_mm256_shuffle_epi8 ( ) {
#[ rustfmt::skip ]
let a = _mm256_setr_epi8 (
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 ,
) ;
#[ rustfmt::skip ]
let b = _mm256_setr_epi8 (
4 , 128 u8 as i8 , 4 , 3 , 24 , 12 , 6 , 19 ,
12 , 5 , 5 , 10 , 4 , 1 , 8 , 0 ,
4 , 128 u8 as i8 , 4 , 3 , 24 , 12 , 6 , 19 ,
12 , 5 , 5 , 10 , 4 , 1 , 8 , 0 ,
) ;
#[ rustfmt::skip ]
let expected = _mm256_setr_epi8 (
5 , 0 , 5 , 4 , 9 , 13 , 7 , 4 ,
13 , 6 , 6 , 11 , 5 , 2 , 9 , 1 ,
21 , 0 , 21 , 20 , 25 , 29 , 23 , 20 ,
29 , 22 , 22 , 27 , 21 , 18 , 25 , 17 ,
) ;
let r = _mm256_shuffle_epi8 ( a , b ) ;
assert_eq_m256i ( r , expected ) ;
}
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " avx2 " ) ]
unsafe fn test_mm256_permute2x128_si256 ( ) {
let a = _mm256_setr_epi64x ( 100 , 200 , 500 , 600 ) ;
let b = _mm256_setr_epi64x ( 300 , 400 , 700 , 800 ) ;
let r = _mm256_permute2x128_si256 ::< 0b00_01_00_11 > ( a , b ) ;
let e = _mm256_setr_epi64x ( 700 , 800 , 500 , 600 ) ;
assert_eq_m256i ( r , e ) ;
}
2024-05-13 13:26:33 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " avx2 " ) ]
unsafe fn test_mm256_permutevar8x32_epi32 ( ) {
let a = _mm256_setr_epi32 ( 100 , 200 , 300 , 400 , 500 , 600 , 700 , 800 ) ;
let idx = _mm256_setr_epi32 ( 7 , 6 , 5 , 4 , 3 , 2 , 1 , 0 ) ;
let r = _mm256_setr_epi32 ( 800 , 700 , 600 , 500 , 400 , 300 , 200 , 100 ) ;
let e = _mm256_permutevar8x32_epi32 ( a , idx ) ;
assert_eq_m256i ( r , e ) ;
}
2024-06-30 11:28:14 +00:00
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " avx2 " ) ]
#[ cfg(not(jit)) ]
unsafe fn test_mm_cvtps_epi32 ( ) {
let floats : [ f32 ; 4 ] = [ 1.5 , - 2.5 , i32 ::MAX as f32 + 1.0 , f32 ::NAN ] ;
let float_vec = _mm_loadu_ps ( floats . as_ptr ( ) ) ;
let int_vec = _mm_cvtps_epi32 ( float_vec ) ;
let mut ints : [ i32 ; 4 ] = [ 0 ; 4 ] ;
_mm_storeu_si128 ( ints . as_mut_ptr ( ) as * mut __m128i , int_vec ) ;
// this is very different from `floats.map(|f| f as i32)`!
let expected_ints : [ i32 ; 4 ] = [ 2 , - 2 , i32 ::MIN , i32 ::MIN ] ;
assert_eq! ( ints , expected_ints ) ;
}
#[ cfg(target_arch = " x86_64 " ) ]
#[ target_feature(enable = " avx2 " ) ]
unsafe fn test_mm_cvttps_epi32 ( ) {
let floats : [ f32 ; 4 ] = [ 1.5 , - 2.5 , i32 ::MAX as f32 + 1.0 , f32 ::NAN ] ;
let float_vec = _mm_loadu_ps ( floats . as_ptr ( ) ) ;
let int_vec = _mm_cvttps_epi32 ( float_vec ) ;
let mut ints : [ i32 ; 4 ] = [ 0 ; 4 ] ;
_mm_storeu_si128 ( ints . as_mut_ptr ( ) as * mut __m128i , int_vec ) ;
// this is very different from `floats.map(|f| f as i32)`!
let expected_ints : [ i32 ; 4 ] = [ 1 , - 2 , i32 ::MIN , i32 ::MIN ] ;
assert_eq! ( ints , expected_ints ) ;
}
2020-06-20 13:15:28 +00:00
fn test_checked_mul ( ) {
let u : Option < u8 > = u8 ::from_str_radix ( " 1000 " , 10 ) . ok ( ) ;
assert_eq! ( u , None ) ;
assert_eq! ( 1 u8 . checked_mul ( 255 u8 ) , Some ( 255 u8 ) ) ;
assert_eq! ( 255 u8 . checked_mul ( 255 u8 ) , None ) ;
assert_eq! ( 1 i8 . checked_mul ( 127 i8 ) , Some ( 127 i8 ) ) ;
assert_eq! ( 127 i8 . checked_mul ( 127 i8 ) , None ) ;
assert_eq! ( ( - 1 i8 ) . checked_mul ( - 127 i8 ) , Some ( 127 i8 ) ) ;
assert_eq! ( 1 i8 . checked_mul ( - 128 i8 ) , Some ( - 128 i8 ) ) ;
assert_eq! ( ( - 128 i8 ) . checked_mul ( - 128 i8 ) , None ) ;
2020-11-03 10:00:04 +00:00
assert_eq! ( 1 u64 . checked_mul ( u64 ::MAX ) , Some ( u64 ::MAX ) ) ;
assert_eq! ( u64 ::MAX . checked_mul ( u64 ::MAX ) , None ) ;
assert_eq! ( 1 i64 . checked_mul ( i64 ::MAX ) , Some ( i64 ::MAX ) ) ;
assert_eq! ( i64 ::MAX . checked_mul ( i64 ::MAX ) , None ) ;
assert_eq! ( ( - 1 i64 ) . checked_mul ( i64 ::MIN + 1 ) , Some ( i64 ::MAX ) ) ;
assert_eq! ( 1 i64 . checked_mul ( i64 ::MIN ) , Some ( i64 ::MIN ) ) ;
assert_eq! ( i64 ::MIN . checked_mul ( i64 ::MIN ) , None ) ;
2020-06-20 13:15:28 +00:00
}
2019-07-24 15:23:23 +00:00
#[ derive(PartialEq) ]
enum LoopState {
Continue ( ( ) ) ,
2023-04-29 12:00:43 +00:00
Break ( ( ) ) ,
2019-07-24 15:23:23 +00:00
}
pub enum Instruction {
Increment ,
Loop ,
}
fn map ( a : Option < ( u8 , Box < Instruction > ) > ) -> Option < Box < Instruction > > {
match a {
None = > None ,
Some ( ( _ , instr ) ) = > Some ( instr ) ,
}
}