summaryrefslogtreecommitdiff
path: root/libavutil
diff options
context:
space:
mode:
authorRĂ©mi Denis-Courmont <remi@remlab.net>2022-09-12 18:53:19 +0300
committerJames Almer <jamrial@gmail.com>2022-09-13 16:50:43 -0300
commitdf2057041b6079bea2fc5e6b31b00756f3da7d54 (patch)
treee35cb750552bb771dfca91299a23ad22c5153124 /libavutil
parentff14e3739393147b4596245ea511ec43a4ce6448 (diff)
lavu/riscv: byte-swap operations
If the target supports the Basic bit-manipulation (Zbb) extension, then the REV8 instruction is available to reverse byte order. Note that this instruction only exists at the "XLEN" register size, so we need to right shift the result down to the data width. If Zbb is not supported, then this patchset does nothing. Support for run-time detection is left for the future. Currently, there are no bits in auxv/ELF HWCAP for Z-extensions, so there are no clean ways to do this.
Diffstat (limited to 'libavutil')
-rw-r--r--libavutil/bswap.h2
-rw-r--r--libavutil/riscv/bswap.h74
2 files changed, 76 insertions, 0 deletions
diff --git a/libavutil/bswap.h b/libavutil/bswap.h
index 91cb79538d..4840ab433f 100644
--- a/libavutil/bswap.h
+++ b/libavutil/bswap.h
@@ -40,6 +40,8 @@
# include "arm/bswap.h"
#elif ARCH_AVR32
# include "avr32/bswap.h"
+#elif ARCH_RISCV
+# include "riscv/bswap.h"
#elif ARCH_SH4
# include "sh4/bswap.h"
#elif ARCH_X86
diff --git a/libavutil/riscv/bswap.h b/libavutil/riscv/bswap.h
new file mode 100644
index 0000000000..de1429c0f7
--- /dev/null
+++ b/libavutil/riscv/bswap.h
@@ -0,0 +1,74 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVUTIL_RISCV_BSWAP_H
+#define AVUTIL_RISCV_BSWAP_H
+
+#include <stdint.h>
+#include "config.h"
+#include "libavutil/attributes.h"
+
+#if defined (__riscv_zbb) && (__riscv_zbb > 0) && HAVE_INLINE_ASM
+
+static av_always_inline av_const uintptr_t av_bswap_xlen(uintptr_t x)
+{
+ uintptr_t y;
+
+ __asm__("rev8 %0, %1" : "=r" (y) : "r" (x));
+ return y;
+}
+
+#define av_bswap16 av_bswap16
+
+static av_always_inline av_const uint_fast16_t av_bswap16(uint_fast16_t x)
+{
+ return av_bswap_xlen(x) >> (__riscv_xlen - 16);
+}
+
+#if (__riscv_xlen == 32)
+#define av_bswap32 av_bswap_xlen
+#define av_bswap64 av_bswap64
+
+static av_always_inline av_const uint64_t av_bswap64(uint64_t x)
+{
+ return (((uint64_t)av_bswap32(x)) << 32) | av_bswap32(x >> 32);
+}
+
+#else
+#define av_bswap32 av_bswap32
+
+static av_always_inline av_const uint_fast32_t av_bswap32(uint_fast32_t x)
+{
+ return av_bswap_xlen(x) >> (__riscv_xlen - 32);
+}
+
+#if (__riscv_xlen == 64)
+#define av_bswap64 av_bswap_xlen
+
+#else
+#define av_bswap64 av_bswap64
+
+static av_always_inline av_const uint_fast64_t av_bswap64(uint_fast64_t x)
+{
+ return av_bswap_xlen(x) >> (__riscv_xlen - 64);
+}
+
+#endif /* __riscv_xlen > 64 */
+#endif /* __riscv_xlen > 32 */
+#endif /* __riscv_zbb */
+#endif /* AVUTIL_RISCV_BSWAP_H */