@@ -395,7 +395,132 @@ pub(crate) fn decode_hwcap(key: AuxvType, value: u64) -> Option<Vec<&'static str
395395 }
396396}
397397
398- #[ cfg( not( any( target_arch = "x86_64" , target_arch = "aarch64" ) ) ) ]
398+ #[ cfg( target_arch = "s390x" ) ]
399+ pub ( crate ) fn decode_hwcap ( key : AuxvType , value : u64 ) -> Option < Vec < & ' static str > > {
400+ // AT_HWCAP on s390x: bits from arch/s390/include/asm/elf.h
401+ const HWCAP_NAMES : & [ ( u32 , & str ) ] = & [
402+ ( 0 , "ESAN3" ) ,
403+ ( 1 , "ZARCH" ) ,
404+ ( 2 , "STFLE" ) ,
405+ ( 3 , "MSA" ) ,
406+ ( 4 , "LDISP" ) ,
407+ ( 5 , "EIMM" ) ,
408+ ( 6 , "DFP" ) ,
409+ ( 7 , "HPAGE" ) ,
410+ ( 8 , "ETF3EH" ) ,
411+ ( 9 , "HIGH_GPRS" ) ,
412+ ( 10 , "TE" ) ,
413+ ( 11 , "VXRS" ) ,
414+ ( 12 , "VXRS_BCD" ) ,
415+ ( 13 , "VXRS_EXT" ) ,
416+ ( 14 , "GS" ) ,
417+ ( 15 , "VXRS_EXT2" ) ,
418+ ( 16 , "VXRS_PDE" ) ,
419+ ( 17 , "SORT" ) ,
420+ ( 18 , "DFLT" ) ,
421+ ( 19 , "VXRS_PDE2" ) ,
422+ ( 20 , "NNPA" ) ,
423+ ( 21 , "PCI_MIO" ) ,
424+ ( 22 , "SIE" ) ,
425+ ] ;
426+
427+ // s390x does not currently define AT_HWCAP2 bits
428+ let table = match key {
429+ AuxvType :: Hwcap => HWCAP_NAMES ,
430+ _ => return None ,
431+ } ;
432+
433+ let names: Vec < & str > = table
434+ . iter ( )
435+ . filter ( |( bit, _) | value & ( 1u64 << bit) != 0 )
436+ . map ( |( _, name) | * name)
437+ . collect ( ) ;
438+
439+ if names. is_empty ( ) {
440+ None
441+ } else {
442+ Some ( names)
443+ }
444+ }
445+
446+ #[ cfg( target_arch = "powerpc64" ) ]
447+ pub ( crate ) fn decode_hwcap ( key : AuxvType , value : u64 ) -> Option < Vec < & ' static str > > {
448+ // AT_HWCAP on powerpc64: PPC_FEATURE_* from arch/powerpc/include/uapi/asm/cputable.h
449+ const HWCAP_NAMES : & [ ( u32 , & str ) ] = & [
450+ ( 0 , "PPC_LE" ) ,
451+ ( 1 , "TRUE_LE" ) ,
452+ ( 6 , "PSERIES_PERFMON_COMPAT" ) ,
453+ ( 7 , "VSX" ) ,
454+ ( 8 , "ARCH_2_06" ) ,
455+ ( 9 , "POWER6_EXT" ) ,
456+ ( 10 , "DFP" ) ,
457+ ( 11 , "PA6T" ) ,
458+ ( 12 , "ARCH_2_05" ) ,
459+ ( 13 , "ICACHE_SNOOP" ) ,
460+ ( 14 , "SMT" ) ,
461+ ( 15 , "BOOKE" ) ,
462+ ( 16 , "CELL" ) ,
463+ ( 17 , "POWER5+" ) ,
464+ ( 18 , "POWER5" ) ,
465+ ( 19 , "POWER4" ) ,
466+ ( 20 , "NO_TB" ) ,
467+ ( 21 , "EFP_DOUBLE" ) ,
468+ ( 22 , "EFP_SINGLE" ) ,
469+ ( 23 , "SPE" ) ,
470+ ( 24 , "UNIFIED_CACHE" ) ,
471+ ( 25 , "4xxMAC" ) ,
472+ ( 26 , "MMU" ) ,
473+ ( 27 , "FPU" ) ,
474+ ( 28 , "ALTIVEC" ) ,
475+ ( 29 , "601_INSTR" ) ,
476+ ( 30 , "64" ) ,
477+ ( 31 , "32" ) ,
478+ ] ;
479+
480+ // AT_HWCAP2 on powerpc64: PPC_FEATURE2_* from arch/powerpc/include/uapi/asm/cputable.h
481+ const HWCAP2_NAMES : & [ ( u32 , & str ) ] = & [
482+ ( 17 , "MMA" ) ,
483+ ( 18 , "ARCH_3_1" ) ,
484+ ( 19 , "HTM_NO_SUSPEND" ) ,
485+ ( 20 , "SCV" ) ,
486+ ( 21 , "DARN" ) ,
487+ ( 22 , "IEEE128" ) ,
488+ ( 23 , "ARCH_3_00" ) ,
489+ ( 24 , "HTM_NOSC" ) ,
490+ ( 25 , "VEC_CRYPTO" ) ,
491+ ( 26 , "TAR" ) ,
492+ ( 27 , "ISEL" ) ,
493+ ( 28 , "EBB" ) ,
494+ ( 29 , "DSCR" ) ,
495+ ( 30 , "HTM" ) ,
496+ ( 31 , "ARCH_2_07" ) ,
497+ ] ;
498+
499+ let table = match key {
500+ AuxvType :: Hwcap => HWCAP_NAMES ,
501+ AuxvType :: Hwcap2 => HWCAP2_NAMES ,
502+ _ => return None ,
503+ } ;
504+
505+ let names: Vec < & str > = table
506+ . iter ( )
507+ . filter ( |( bit, _) | value & ( 1u64 << bit) != 0 )
508+ . map ( |( _, name) | * name)
509+ . collect ( ) ;
510+
511+ if names. is_empty ( ) {
512+ None
513+ } else {
514+ Some ( names)
515+ }
516+ }
517+
518+ #[ cfg( not( any(
519+ target_arch = "x86_64" ,
520+ target_arch = "aarch64" ,
521+ target_arch = "s390x" ,
522+ target_arch = "powerpc64"
523+ ) ) ) ]
399524pub fn decode_hwcap ( _key : AuxvType , _value : u64 ) -> Option < Vec < & ' static str > > {
400525 None
401526}
0 commit comments