diff options
author | Darren Hsieh <darren.hsieh@sifive.com> | 2023-04-01 07:11:11 -0700 |
---|---|---|
committer | libyuv LUCI CQ <libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-06 15:58:29 +0000 |
commit | aa47d668d8c531b0e4e775b236d25b3ad08372f0 (patch) | |
tree | 5560098a50850ea20cb3745dfe79a6ea45f9157c /source/cpu_id.cc | |
parent | ec48e4328eac1f137dc6eff8d6f1dd38810fe583 (diff) | |
download | libyuv-aa47d668d8c531b0e4e775b236d25b3ad08372f0.tar.gz |
Add riscv cpu info detection.
* Supports:
* The standard single-letter Vector detection.
* Vector fp16 detection.
Signed-off-by: Darren Hsieh <darren.hsieh@sifive.com>
Change-Id: Ia7ee1bd8ec1a990f1b2b1700805942e99c0aa87b
Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/4401738
Commit-Queue: Frank Barchard <fbarchard@chromium.org>
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
Diffstat (limited to 'source/cpu_id.cc')
-rw-r--r-- | source/cpu_id.cc | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/source/cpu_id.cc b/source/cpu_id.cc index 13e3da7b..409456e8 100644 --- a/source/cpu_id.cc +++ b/source/cpu_id.cc @@ -191,6 +191,63 @@ LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name) { return flag; } +LIBYUV_API SAFEBUFFERS int RiscvCpuCaps(const char* cpuinfo_name) { + char cpuinfo_line[512]; + int flag = 0x0; + FILE* f = fopen(cpuinfo_name, "r"); + 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)) { + 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) { + const int isa_len = strlen(isa); + // 5 ISA characters + 1 new-line character + if (isa_len < 6) { + 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. + int otherExts_len = 0; + char* otherExts = strpbrk(isa, "zxs"); + if (otherExts) { + otherExts_len = strlen(otherExts); + // Multi-letter extensions are seperated by a single underscore + // as described in RISC-V User-Level ISA V2.2. + char* ext = strtok(otherExts, "_"); + while (ext) { + // Search for the ZVFH (Vector FP16) extension. + // The ZVFH implied the (Scalar FP16)ZFH extension. + if (!strcmp(ext, "zvfh") || !strcmp(ext, "zvfh\n")) { + flag |= kCpuHasRVVZVFH; + } + ext = strtok(NULL, "_"); + } + } + const int std_isa_len = isa_len - otherExts_len - 5 - 1; + // Detect the v in the standard single-letter extensions. + // Skip optional Zve* and Zvl* extensions detection at otherExts. + if (memchr(isa, 'v', std_isa_len)) { + // The RVV implied the F extension. + flag |= kCpuHasRVV; + } + } + } + } + fclose(f); + return flag; +} + // TODO(fbarchard): Consider read_loongarch_ir(). #define LOONGARCH_CFG2 0x2 #define LOONGARCH_CFG2_LSX (1 << 6) @@ -277,6 +334,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; } |