@@ -25,6 +25,11 @@ fn compare256(src0: &[u8; 256], src1: &[u8; 256]) -> usize {
2525 return unsafe { neon:: compare256 ( src0, src1) } ;
2626 }
2727
28+ #[ cfg( all( target_arch = "loongarch64" , feature = "lsx" ) ) ]
29+ if crate :: cpu_features:: is_enabled_lsx ( ) {
30+ return unsafe { lsx:: compare256 ( src0, src1) } ;
31+ }
32+
2833 #[ cfg( target_arch = "wasm32" ) ]
2934 if crate :: cpu_features:: is_enabled_simd128 ( ) {
3035 return wasm32:: compare256 ( src0, src1) ;
@@ -363,6 +368,59 @@ mod avx512 {
363368 }
364369}
365370
371+ #[ cfg( all( target_arch = "loongarch64" , feature = "lsx" ) ) ]
372+ mod lsx {
373+ use core:: arch:: loongarch64:: { lsx_vld, lsx_vmskltz_b, lsx_vpickve2gr_w, lsx_vseq_b} ;
374+
375+ #[ target_feature( enable = "lsx" ) ]
376+ pub fn compare256 ( src0 : & [ u8 ; 256 ] , src1 : & [ u8 ; 256 ] ) -> usize {
377+ let src0 = src0. chunks_exact ( 16 ) ;
378+ let src1 = src1. chunks_exact ( 16 ) ;
379+
380+ let mut len = 0 ;
381+
382+ unsafe {
383+ for ( chunk0, chunk1) in src0. zip ( src1) {
384+ let a = lsx_vld :: < 0 > ( chunk0. as_ptr ( ) as * const i8 ) ;
385+ let b = lsx_vld :: < 0 > ( chunk1. as_ptr ( ) as * const i8 ) ;
386+
387+ // element-wise compare of the 8-bit elements
388+ // 0xff if equal, otherwise 0
389+ let v = lsx_vseq_b ( a, b) ;
390+
391+ // bootleg movemask implementation
392+ let mask = lsx_vpickve2gr_w :: < 0 > ( lsx_vmskltz_b ( v) ) ;
393+
394+ if mask != 0xFFFF {
395+ let match_byte = mask. trailing_ones ( ) ;
396+ return len + match_byte as usize ;
397+ }
398+
399+ len += 16 ;
400+ }
401+ }
402+
403+ 256
404+ }
405+
406+ #[ test]
407+ fn test_compare256 ( ) {
408+ if crate :: cpu_features:: is_enabled_lsx ( ) {
409+ let str1 = [ b'a' ; super :: MAX_COMPARE_SIZE ] ;
410+ let mut str2 = [ b'a' ; super :: MAX_COMPARE_SIZE ] ;
411+
412+ for i in 0 ..str1. len ( ) {
413+ str2[ i] = 0 ;
414+
415+ let match_len = unsafe { compare256 ( & str1, & str2) } ;
416+ assert_eq ! ( match_len, i) ;
417+
418+ str2[ i] = b'a' ;
419+ }
420+ }
421+ }
422+ }
423+
366424#[ cfg( target_arch = "wasm32" ) ]
367425mod wasm32 {
368426 use core:: arch:: wasm32:: { u8x16_bitmask, u8x16_eq, v128, v128_load} ;
0 commit comments