aboutsummaryrefslogtreecommitdiff
path: root/source/cpu_id.cc
diff options
context:
space:
mode:
authorDarren Hsieh <darren.hsieh@sifive.com>2023-04-01 07:11:11 -0700
committerlibyuv LUCI CQ <libyuv-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-06 15:58:29 +0000
commitaa47d668d8c531b0e4e775b236d25b3ad08372f0 (patch)
tree5560098a50850ea20cb3745dfe79a6ea45f9157c /source/cpu_id.cc
parentec48e4328eac1f137dc6eff8d6f1dd38810fe583 (diff)
downloadlibyuv-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.cc61
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;
}