diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-09-02 07:11:13 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-09-02 07:11:13 +0000 |
commit | e50ecd2fbbc0c8776b2011ce02311754be470d28 (patch) | |
tree | 318b601d40604f7933f7ff0b364bcea559c6d35b /files/source/cpu_id.cc | |
parent | 1fa594b2aa576922fd01c702585fcdb1a2e6f311 (diff) | |
parent | dd06f86b98527b6b6425ea679bea5cc347f5afb4 (diff) | |
download | libyuv-e50ecd2fbbc0c8776b2011ce02311754be470d28.tar.gz |
Snap for 10754184 from dd06f86b98527b6b6425ea679bea5cc347f5afb4 to mainline-extservices-releaseaml_ext_341716000aml_ext_341620040aml_ext_341518010aml_ext_341414010aml_ext_341317010aml_ext_341131030android14-mainline-extservices-release
Change-Id: I604d2bf97307a6550c8d4822f78ba001f5c53597
Diffstat (limited to 'files/source/cpu_id.cc')
-rw-r--r-- | files/source/cpu_id.cc | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/files/source/cpu_id.cc b/files/source/cpu_id.cc index 56fe60e4..0c4a1581 100644 --- a/files/source/cpu_id.cc +++ b/files/source/cpu_id.cc @@ -40,7 +40,6 @@ extern "C" { // cpu_info_ variable for SIMD instruction sets detected. LIBYUV_API int cpu_info_ = 0; -// TODO(fbarchard): Consider using int for cpuid so casting is not needed. // Low level cpuid for X86. #if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ defined(__x86_64__)) && \ @@ -108,14 +107,14 @@ void CpuId(int eax, int ecx, int* cpu_info) { // } // For VS2013 and earlier 32 bit, the _xgetbv(0) optimizer produces bad code. // https://code.google.com/p/libyuv/issues/detail?id=529 -#if defined(_M_IX86) && (_MSC_VER < 1900) +#if defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER < 1900) #pragma optimize("g", off) #endif #if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \ defined(__x86_64__)) && \ !defined(__pnacl__) && !defined(__CLR_VER) && !defined(__native_client__) // X86 CPUs have xgetbv to detect OS saves high parts of ymm registers. -int GetXCR0() { +static int GetXCR0() { int xcr0 = 0; #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) xcr0 = (int)_xgetbv(0); // VS2010 SP1 required. NOLINT @@ -129,7 +128,7 @@ int GetXCR0() { #define GetXCR0() 0 #endif // defined(_M_IX86) || defined(_M_X64) .. // Return optimization to previous setting. -#if defined(_M_IX86) && (_MSC_VER < 1900) +#if defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER < 1900) #pragma optimize("g", on) #endif @@ -137,13 +136,14 @@ int GetXCR0() { // For Arm, but public to allow testing on any CPU LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) { char cpuinfo_line[512]; - FILE* f = fopen(cpuinfo_name, "r"); + FILE* f = fopen(cpuinfo_name, "re"); if (!f) { // Assume Neon if /proc/cpuinfo is unavailable. // This will occur for Chrome sandbox for Pepper or Render process. return kCpuHasNEON; } - while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { + memset(cpuinfo_line, 0, sizeof(cpuinfo_line)); + while (fgets(cpuinfo_line, sizeof(cpuinfo_line), f)) { if (memcmp(cpuinfo_line, "Features", 8) == 0) { char* p = strstr(cpuinfo_line, " neon"); if (p && (p[5] == ' ' || p[5] == '\n')) { @@ -162,17 +162,90 @@ LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) { return 0; } -// TODO(fbarchard): Consider read_msa_ir(). +LIBYUV_API SAFEBUFFERS int RiscvCpuCaps(const char* cpuinfo_name) { + char cpuinfo_line[512]; + int flag = 0; + FILE* f = fopen(cpuinfo_name, "re"); + if (!f) { +#if defined(__riscv_vector) + // Assume RVV if /proc/cpuinfo is unavailable. + // This will occur for Chrome sandbox for Pepper or Render process. + return kCpuHasRVV; +#else + return 0; +#endif + } + memset(cpuinfo_line, 0, sizeof(cpuinfo_line)); + while (fgets(cpuinfo_line, sizeof(cpuinfo_line), f)) { + if (memcmp(cpuinfo_line, "isa", 3) == 0) { + // ISA string must begin with rv64{i,e,g} for a 64-bit processor. + char* isa = strstr(cpuinfo_line, "rv64"); + if (isa) { + size_t isa_len = strlen(isa); + char* extensions; + size_t extensions_len = 0; + size_t std_isa_len; + // Remove the new-line character at the end of string + if (isa[isa_len - 1] == '\n') { + isa[--isa_len] = '\0'; + } + // 5 ISA characters + if (isa_len < 5) { + fclose(f); + return 0; + } + // Skip {i,e,g} canonical checking. + // Skip rvxxx + isa += 5; + // Find the very first occurrence of 's', 'x' or 'z'. + // To detect multi-letter standard, non-standard, and + // supervisor-level extensions. + extensions = strpbrk(isa, "zxs"); + if (extensions) { + // Multi-letter extensions are seperated by a single underscore + // as described in RISC-V User-Level ISA V2.2. + char* ext = strtok(extensions, "_"); + extensions_len = strlen(extensions); + while (ext) { + // Search for the ZVFH (Vector FP16) extension. + if (!strcmp(ext, "zvfh")) { + flag |= kCpuHasRVVZVFH; + } + ext = strtok(NULL, "_"); + } + } + std_isa_len = isa_len - extensions_len - 5; + // Detect the v in the standard single-letter extensions. + if (memchr(isa, 'v', std_isa_len)) { + // The RVV implied the F extension. + flag |= kCpuHasRVV; + } + } + } +#if defined(__riscv_vector) + // Assume RVV if /proc/cpuinfo is from x86 host running QEMU. + else if ((memcmp(cpuinfo_line, "vendor_id\t: GenuineIntel", 24) == 0) || + (memcmp(cpuinfo_line, "vendor_id\t: AuthenticAMD", 24) == 0)) { + fclose(f); + return kCpuHasRVV; + } +#endif + } + fclose(f); + return flag; +} + LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name) { char cpuinfo_line[512]; - int flag = 0x0; - FILE* f = fopen(cpuinfo_name, "r"); + int flag = 0; + FILE* f = fopen(cpuinfo_name, "re"); if (!f) { // Assume nothing if /proc/cpuinfo is unavailable. // This will occur for Chrome sandbox for Pepper or Render process. return 0; } - while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) { + memset(cpuinfo_line, 0, sizeof(cpuinfo_line)); + while (fgets(cpuinfo_line, sizeof(cpuinfo_line), f)) { if (memcmp(cpuinfo_line, "cpu model", 9) == 0) { // Workaround early kernel without MSA in ASEs line. if (strstr(cpuinfo_line, "Loongson-2K")) { @@ -191,14 +264,13 @@ LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name) { return flag; } -// TODO(fbarchard): Consider read_loongarch_ir(). #define LOONGARCH_CFG2 0x2 #define LOONGARCH_CFG2_LSX (1 << 6) #define LOONGARCH_CFG2_LASX (1 << 7) #if defined(__loongarch__) LIBYUV_API SAFEBUFFERS int LoongarchCpuCaps(void) { - int flag = 0x0; + int flag = 0; uint32_t cfg2 = 0; __asm__ volatile("cpucfg %0, %1 \n\t" : "+&r"(cfg2) : "r"(LOONGARCH_CFG2)); @@ -277,6 +349,10 @@ static SAFEBUFFERS int GetCpuFlags(void) { #endif cpu_info |= kCpuHasARM; #endif // __arm__ +#if defined(__riscv) && defined(__linux__) + cpu_info = RiscvCpuCaps("/proc/cpuinfo"); + cpu_info |= kCpuHasRISCV; +#endif // __riscv cpu_info |= kCpuInitialized; return cpu_info; } |