mrs.inc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #if __has_include(<sys/auxv.h>)
  2. #include <sys/auxv.h>
  3. #define HAVE_SYS_AUXV_H
  4. #endif
  5. static void __init_cpu_features_constructor(unsigned long hwcap,
  6. const __ifunc_arg_t *arg) {
  7. unsigned long long feat = 0;
  8. #define setCPUFeature(F) feat |= 1ULL << F
  9. #define getCPUFeature(id, ftr) __asm__("mrs %0, " #id : "=r"(ftr))
  10. #define extractBits(val, start, number) \
  11. (val & ((1ULL << number) - 1ULL) << start) >> start
  12. unsigned long hwcap2 = 0;
  13. if (hwcap & _IFUNC_ARG_HWCAP)
  14. hwcap2 = arg->_hwcap2;
  15. if (hwcap & HWCAP_CRC32)
  16. setCPUFeature(FEAT_CRC);
  17. if (hwcap & HWCAP_PMULL)
  18. setCPUFeature(FEAT_PMULL);
  19. if (hwcap & HWCAP_FLAGM)
  20. setCPUFeature(FEAT_FLAGM);
  21. if (hwcap2 & HWCAP2_FLAGM2)
  22. setCPUFeature(FEAT_FLAGM2);
  23. if (hwcap & HWCAP_SM4)
  24. setCPUFeature(FEAT_SM4);
  25. if (hwcap & HWCAP_ASIMDDP)
  26. setCPUFeature(FEAT_DOTPROD);
  27. if (hwcap & HWCAP_ASIMDFHM)
  28. setCPUFeature(FEAT_FP16FML);
  29. if (hwcap & HWCAP_FPHP)
  30. setCPUFeature(FEAT_FP16);
  31. if (hwcap & HWCAP_DIT)
  32. setCPUFeature(FEAT_DIT);
  33. if (hwcap & HWCAP_ASIMDRDM)
  34. setCPUFeature(FEAT_RDM);
  35. if (hwcap & HWCAP_AES)
  36. setCPUFeature(FEAT_AES);
  37. if (hwcap & HWCAP_SHA1)
  38. setCPUFeature(FEAT_SHA1);
  39. if (hwcap & HWCAP_SHA2)
  40. setCPUFeature(FEAT_SHA2);
  41. if (hwcap & HWCAP_JSCVT)
  42. setCPUFeature(FEAT_JSCVT);
  43. if (hwcap & HWCAP_FCMA)
  44. setCPUFeature(FEAT_FCMA);
  45. if (hwcap & HWCAP_SB)
  46. setCPUFeature(FEAT_SB);
  47. if (hwcap & HWCAP_SSBS) {
  48. setCPUFeature(FEAT_SSBS);
  49. setCPUFeature(FEAT_SSBS2);
  50. }
  51. if (hwcap2 & HWCAP2_MTE) {
  52. setCPUFeature(FEAT_MEMTAG);
  53. setCPUFeature(FEAT_MEMTAG2);
  54. }
  55. if (hwcap2 & HWCAP2_MTE3)
  56. setCPUFeature(FEAT_MEMTAG3);
  57. if (hwcap2 & HWCAP2_SVEAES)
  58. setCPUFeature(FEAT_SVE_AES);
  59. if (hwcap2 & HWCAP2_SVEPMULL)
  60. setCPUFeature(FEAT_SVE_PMULL128);
  61. if (hwcap2 & HWCAP2_SVEBITPERM)
  62. setCPUFeature(FEAT_SVE_BITPERM);
  63. if (hwcap2 & HWCAP2_SVESHA3)
  64. setCPUFeature(FEAT_SVE_SHA3);
  65. if (hwcap2 & HWCAP2_SVESM4)
  66. setCPUFeature(FEAT_SVE_SM4);
  67. if (hwcap2 & HWCAP2_DCPODP)
  68. setCPUFeature(FEAT_DPB2);
  69. if (hwcap & HWCAP_ATOMICS)
  70. setCPUFeature(FEAT_LSE);
  71. if (hwcap2 & HWCAP2_RNG)
  72. setCPUFeature(FEAT_RNG);
  73. if (hwcap2 & HWCAP2_I8MM)
  74. setCPUFeature(FEAT_I8MM);
  75. if (hwcap2 & HWCAP2_EBF16)
  76. setCPUFeature(FEAT_EBF16);
  77. if (hwcap2 & HWCAP2_SVE_EBF16)
  78. setCPUFeature(FEAT_SVE_EBF16);
  79. if (hwcap2 & HWCAP2_DGH)
  80. setCPUFeature(FEAT_DGH);
  81. if (hwcap2 & HWCAP2_FRINT)
  82. setCPUFeature(FEAT_FRINTTS);
  83. if (hwcap2 & HWCAP2_SVEI8MM)
  84. setCPUFeature(FEAT_SVE_I8MM);
  85. if (hwcap2 & HWCAP2_SVEF32MM)
  86. setCPUFeature(FEAT_SVE_F32MM);
  87. if (hwcap2 & HWCAP2_SVEF64MM)
  88. setCPUFeature(FEAT_SVE_F64MM);
  89. if (hwcap2 & HWCAP2_BTI)
  90. setCPUFeature(FEAT_BTI);
  91. if (hwcap2 & HWCAP2_RPRES)
  92. setCPUFeature(FEAT_RPRES);
  93. if (hwcap2 & HWCAP2_WFXT)
  94. setCPUFeature(FEAT_WFXT);
  95. if (hwcap2 & HWCAP2_SME)
  96. setCPUFeature(FEAT_SME);
  97. if (hwcap2 & HWCAP2_SME2)
  98. setCPUFeature(FEAT_SME2);
  99. if (hwcap2 & HWCAP2_SME_I16I64)
  100. setCPUFeature(FEAT_SME_I64);
  101. if (hwcap2 & HWCAP2_SME_F64F64)
  102. setCPUFeature(FEAT_SME_F64);
  103. if (hwcap2 & HWCAP2_MOPS)
  104. setCPUFeature(FEAT_MOPS);
  105. if (hwcap & HWCAP_CPUID) {
  106. unsigned long ftr;
  107. getCPUFeature(ID_AA64ISAR1_EL1, ftr);
  108. /* ID_AA64ISAR1_EL1.SPECRES >= 0b0001 */
  109. if (extractBits(ftr, 40, 4) >= 0x1)
  110. setCPUFeature(FEAT_PREDRES);
  111. /* ID_AA64ISAR1_EL1.LS64 >= 0b0001 */
  112. if (extractBits(ftr, 60, 4) >= 0x1)
  113. setCPUFeature(FEAT_LS64);
  114. /* ID_AA64ISAR1_EL1.LS64 >= 0b0010 */
  115. if (extractBits(ftr, 60, 4) >= 0x2)
  116. setCPUFeature(FEAT_LS64_V);
  117. /* ID_AA64ISAR1_EL1.LS64 >= 0b0011 */
  118. if (extractBits(ftr, 60, 4) >= 0x3)
  119. setCPUFeature(FEAT_LS64_ACCDATA);
  120. }
  121. if (hwcap & HWCAP_FP) {
  122. setCPUFeature(FEAT_FP);
  123. // FP and AdvSIMD fields have the same value
  124. setCPUFeature(FEAT_SIMD);
  125. }
  126. if (hwcap & HWCAP_DCPOP)
  127. setCPUFeature(FEAT_DPB);
  128. if (hwcap & HWCAP_LRCPC)
  129. setCPUFeature(FEAT_RCPC);
  130. if (hwcap & HWCAP_ILRCPC)
  131. setCPUFeature(FEAT_RCPC2);
  132. if (hwcap2 & HWCAP2_LRCPC3)
  133. setCPUFeature(FEAT_RCPC3);
  134. if (hwcap2 & HWCAP2_BF16)
  135. setCPUFeature(FEAT_BF16);
  136. if (hwcap2 & HWCAP2_SVEBF16)
  137. setCPUFeature(FEAT_SVE_BF16);
  138. if (hwcap & HWCAP_SVE)
  139. setCPUFeature(FEAT_SVE);
  140. if (hwcap2 & HWCAP2_SVE2)
  141. setCPUFeature(FEAT_SVE2);
  142. if (hwcap & HWCAP_SHA3)
  143. setCPUFeature(FEAT_SHA3);
  144. setCPUFeature(FEAT_INIT);
  145. __atomic_store_n(&__aarch64_cpu_features.features, feat, __ATOMIC_RELAXED);
  146. }