aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan E. Egge <unlord@xiph.org>2024-03-16 10:12:09 -0400
committerNathan E. Egge <unlord@xiph.org>2024-05-06 14:15:44 -0400
commitfc4763c5a4d31aa08f3a0671b2111fbcb67f378d (patch)
treec2d725d6ad61700763411ca69e51592a061131e2
parentc7df9a3e65a8d74c57131d379db93856c38ae47c (diff)
downloadlibdav1d-fc4763c5a4d31aa08f3a0671b2111fbcb67f378d.tar.gz
riscv: Check for standards compliant RVV 1.0+
-rw-r--r--src/meson.build1
-rw-r--r--src/riscv/64/cpu.S44
-rw-r--r--src/riscv/cpu.c4
3 files changed, 48 insertions, 1 deletions
diff --git a/src/meson.build b/src/meson.build
index cd19b70..e6153a5 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -260,6 +260,7 @@ if is_asm_enabled
)
if host_machine.cpu_family() == 'riscv64'
libdav1d_sources += files(
+ 'riscv/64/cpu.S',
'riscv/64/itx.S',
)
endif
diff --git a/src/riscv/64/cpu.S b/src/riscv/64/cpu.S
new file mode 100644
index 0000000..b0e76f6
--- /dev/null
+++ b/src/riscv/64/cpu.S
@@ -0,0 +1,44 @@
+/******************************************************************************
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2024, Nathan Egge
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+#include "src/riscv/asm.S"
+
+// This function detects non-compliant RVV 0.7.1 hardware which reports support
+// for the V extension through HWCAP, by intentionally setting tail and mask
+// agnostic vector configurations that were only introduced in RVV 0.9 spec.
+// Existing non-compliant (pre RVV 1.0) hardware will set the VILL bit in VTYPE
+// (indicating an illegal vector configuration) which is stored in the XLEN-1
+// bit position, thus a simple sign check is sufficient for detection.
+// This work around is inexpensive and harmless on compliant hardware, but we
+// should still consider removing it once all non-compliant RVV 0.7.1 hardware
+// is out of service.
+function has_compliant_rvv, export=1, ext=v
+ vsetvli t0, zero, e8, m1, ta, ma
+ csrr a0, vtype
+ sgtz a0, a0
+ ret
+endfunc
diff --git a/src/riscv/cpu.c b/src/riscv/cpu.c
index 1637710..30e1354 100644
--- a/src/riscv/cpu.c
+++ b/src/riscv/cpu.c
@@ -38,11 +38,13 @@
#endif
+int dav1d_has_compliant_rvv(void);
+
COLD unsigned dav1d_get_cpu_flags_riscv(void) {
unsigned flags = 0;
#if defined(HAVE_GETAUXVAL)
unsigned long hw_cap = getauxval(AT_HWCAP);
- flags |= (hw_cap & HWCAP_RVV) ? DAV1D_RISCV_CPU_FLAG_V : 0;
+ flags |= (hw_cap & HWCAP_RVV) && dav1d_has_compliant_rvv() ? DAV1D_RISCV_CPU_FLAG_V : 0;
#endif
return flags;