Commit f924a86518 for ffmpeg
commit f924a86518aabac74db01f733c0023c216dfffff
Author: Martin Storsjö <martin@martin.st>
Date: Fri Mar 22 10:58:36 2024 +0200
arm/aarch64: Add helpers for debug printing from assembly
These currently allow printing GPRs, SIMD vectors and memory.
GPRs are printed as signed decimal and unsigned hexadecimal.
SIMD vectors are printed as signed or unsigned decimal, as either
8, 16 or 32 bit elements.
Memory can be dumped, interpreted as a stored SIMD vector, by
specifying a base register and how many vectors to read from that
address.
Usage example:
DUMP_SIMD_U8("input", 4, 5) /* Printing v4-v5 as 8 bit unsigned elments */
DUMP_SIMD_S16("sum", 6, 6) /* Printing v6 as 16 bit signed elments */
DUMP_GPR("w,h", 4, 5) /* Printing x4-x5 */
Which prints:
3450: input:
v04.16b = { 201, 1, 245, 0, 139, 0, 225, 1, 33, 1, 254, 0, 41, 2, 212, 1 }
3451: sum:
v06.8h = { 20394, -23720, -30625, 32619, -28321, 11312, 30270, 32051 }
3468: w,h:
x04 = 16 (0x10)
x05 = 64 (0x40)
(or)
3468: w,h:
x04 = -2401053092612145136 (0xdeadbeef00000010)
x05 = -2401053092612145148 (0xdeadbeef00000004)
For inspecting memory:
DUMP_MEM_S16("out", x0, 2) /* Print 2 vectors worth of data from x0, as s16 */
Which can print:
3523: out:
v00.8h = { 12340, 18058, 21605, -10848, -32395, -26577, -15192, 26296 }
v01.8h = { 1998, 1722, 24014, -17100, 2150, -26619, -23289, -4052 }
Using these macros requires linking in the debug printing helper
functions, which can be enabled by passing --enable-asm-debug to
the configure command.
diff --git a/configure b/configure
index ccc46895de..c37cedbbe0 100755
--- a/configure
+++ b/configure
@@ -541,6 +541,7 @@ Developer options (useful when working on FFmpeg itself):
--disable-shader-compression don't compress shader code even when possible
--disable-resource-compression don't compress resources even when possible
--disable-version-tracking don't include the git/release version in the build
+ --enable-asm-debug include functions for assembly debugging
NOTE: Object files are built at the place where configure is launched.
EOF
@@ -2249,6 +2250,7 @@ CONFIG_LIST="
$PROGRAM_LIST
$SUBSYSTEM_LIST
autodetect
+ asm_debug
fontconfig
large_tests
linux_perf
diff --git a/libavutil/aarch64/Makefile b/libavutil/aarch64/Makefile
index b286cfadb0..5508561f3d 100644
--- a/libavutil/aarch64/Makefile
+++ b/libavutil/aarch64/Makefile
@@ -3,6 +3,8 @@ OBJS += aarch64/aes_init.o \
aarch64/float_dsp_init.o \
aarch64/tx_float_init.o \
+OBJS-$(CONFIG_ASM_DEBUG) += aarch64/asm_debug.o
+
ARMV8-OBJS += aarch64/crc.o
NEON-OBJS += aarch64/aes.o \
diff --git a/libavutil/aarch64/asm.S b/libavutil/aarch64/asm.S
index 665202a808..2cda2ca8bc 100644
--- a/libavutil/aarch64/asm.S
+++ b/libavutil/aarch64/asm.S
@@ -370,3 +370,123 @@ ELF .size \name, . - \name
AARCH64_VALIDATE_LINK_REGISTER
.endm
#endif
+
+
+#if CONFIG_ASM_DEBUG
+#undef x18
+.macro call_c func, line, msg, first, last, ptr, offset
+ stp x29, x30, [sp, #-16]!
+ stp x27, x28, [sp, #-16]!
+ stp x25, x26, [sp, #-16]!
+ stp x23, x24, [sp, #-16]!
+ stp x21, x22, [sp, #-16]!
+ stp x19, x20, [sp, #-16]!
+ stp x17, x18, [sp, #-16]!
+ stp x15, x16, [sp, #-16]!
+ stp x13, x14, [sp, #-16]!
+ stp x11, x12, [sp, #-16]!
+ stp x9, x10, [sp, #-16]!
+ stp x7, x8, [sp, #-16]!
+ stp x5, x6, [sp, #-16]!
+ stp x3, x4, [sp, #-16]!
+ stp x1, x2, [sp, #-16]!
+ mrs x30, nzcv
+ stp x30, x0, [sp, #-16]!
+
+ stp q30, q31, [sp, #-32]!
+ stp q28, q29, [sp, #-32]!
+ stp q26, q27, [sp, #-32]!
+ stp q24, q25, [sp, #-32]!
+ stp q22, q23, [sp, #-32]!
+ stp q20, q21, [sp, #-32]!
+ stp q18, q19, [sp, #-32]!
+ stp q16, q17, [sp, #-32]!
+ stp q14, q15, [sp, #-32]!
+ stp q12, q13, [sp, #-32]!
+ stp q10, q11, [sp, #-32]!
+ stp q8, q9, [sp, #-32]!
+ stp q6, q7, [sp, #-32]!
+ stp q4, q5, [sp, #-32]!
+ stp q2, q3, [sp, #-32]!
+ stp q0, q1, [sp, #-32]!
+
+ add x4, \ptr, #\offset
+ ldr x0, =\line
+ adr x1, 777f
+ mov x2, \first
+ mov x3, \last
+ bl X(avpriv_\func)
+
+ ldp q0, q1, [sp], #32
+ ldp q2, q3, [sp], #32
+ ldp q4, q5, [sp], #32
+ ldp q6, q7, [sp], #32
+ ldp q8, q9, [sp], #32
+ ldp q10, q11, [sp], #32
+ ldp q12, q13, [sp], #32
+ ldp q14, q15, [sp], #32
+ ldp q16, q17, [sp], #32
+ ldp q18, q19, [sp], #32
+ ldp q20, q21, [sp], #32
+ ldp q22, q23, [sp], #32
+ ldp q24, q25, [sp], #32
+ ldp q26, q27, [sp], #32
+ ldp q28, q29, [sp], #32
+ ldp q30, q31, [sp], #32
+
+ ldp x30, x0, [sp], #16
+ msr nzcv, x30
+ ldp x1, x2, [sp], #16
+ ldp x3, x4, [sp], #16
+ ldp x5, x6, [sp], #16
+ ldp x7, x8, [sp], #16
+ ldp x9, x10, [sp], #16
+ ldp x11, x12, [sp], #16
+ ldp x13, x14, [sp], #16
+ ldp x15, x16, [sp], #16
+ ldp x17, x18, [sp], #16
+ ldp x19, x20, [sp], #16
+ ldp x21, x22, [sp], #16
+ ldp x23, x24, [sp], #16
+ ldp x25, x26, [sp], #16
+ ldp x27, x28, [sp], #16
+ ldp x29, x30, [sp], #16
+.endm
+
+#ifdef __APPLE__
+#define SEP %%
+#else
+#define SEP ;
+#endif
+
+#define CALL_C(func, msg, first, last, ptr, offset) \
+ call_c func, __LINE__, msg, first, last, ptr, offset SEP \
+ b 778f SEP \
+ 777: \
+ .asciz msg SEP \
+ .align 2 SEP \
+ 778:
+
+#define DUMP_SIMD_S8(msg, first, last) CALL_C(dump_simd_s8, msg, first, last, sp, 0)
+#define DUMP_SIMD_U8(msg, first, last) CALL_C(dump_simd_u8, msg, first, last, sp, 0)
+#define DUMP_SIMD_S16(msg, first, last) CALL_C(dump_simd_s16, msg, first, last, sp, 0)
+#define DUMP_SIMD_U16(msg, first, last) CALL_C(dump_simd_u16, msg, first, last, sp, 0)
+#define DUMP_SIMD_S32(msg, first, last) CALL_C(dump_simd_s32, msg, first, last, sp, 0)
+#define DUMP_SIMD_U32(msg, first, last) CALL_C(dump_simd_u32, msg, first, last, sp, 0)
+#define DUMP_SIMD_S64(msg, first, last) CALL_C(dump_simd_s64, msg, first, last, sp, 0)
+#define DUMP_SIMD_U64(msg, first, last) CALL_C(dump_simd_u64, msg, first, last, sp, 0)
+#define DUMP_SIMD_F32(msg, first, last) CALL_C(dump_simd_f32, msg, first, last, sp, 0)
+#define DUMP_SIMD_F64(msg, first, last) CALL_C(dump_simd_f64, msg, first, last, sp, 0)
+#define DUMP_MEM_S8(msg, reg, n) CALL_C(dump_simd_s8, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U8(msg, reg, n) CALL_C(dump_simd_u8, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_S16(msg, reg, n) CALL_C(dump_simd_s16, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U16(msg, reg, n) CALL_C(dump_simd_u16, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_S32(msg, reg, n) CALL_C(dump_simd_s32, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U32(msg, reg, n) CALL_C(dump_simd_u32, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_S64(msg, reg, n) CALL_C(dump_simd_s64, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U64(msg, reg, n) CALL_C(dump_simd_u64, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_F32(msg, reg, n) CALL_C(dump_simd_f32, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_F64(msg, reg, n) CALL_C(dump_simd_f64, msg, 0, n-1, reg, 0)
+#define DUMP_GPR(msg, first, last) CALL_C(dump_gpr, msg, first, last, sp, 520)
+
+#endif /* CONFIG_ASM_DEBUG */
diff --git a/libavutil/aarch64/asm_debug.c b/libavutil/aarch64/asm_debug.c
new file mode 100644
index 0000000000..105342fc13
--- /dev/null
+++ b/libavutil/aarch64/asm_debug.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2019-2026, Martin Storsjo
+ * 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 "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+void avpriv_dump_simd_s8(int line, const char *msg, int first, int last, const int8_t *ptr);
+void avpriv_dump_simd_s8(int line, const char *msg, int first, int last, const int8_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int8_t *vec = &ptr[16*v];
+ fprintf(stderr, "v%02d.16b = {", v);
+ for (int i = 0; i < 16; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u8(int line, const char *msg, int first, int last, const uint8_t *ptr);
+void avpriv_dump_simd_u8(int line, const char *msg, int first, int last, const uint8_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint8_t *vec = &ptr[16*v];
+ fprintf(stderr, "v%02d.16b = {", v);
+ for (int i = 0; i < 16; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_s16(int line, const char *msg, int first, int last, const int16_t *ptr);
+void avpriv_dump_simd_s16(int line, const char *msg, int first, int last, const int16_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int16_t *vec = &ptr[8*v];
+ fprintf(stderr, "v%02d.8h = {", v);
+ for (int i = 0; i < 8; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u16(int line, const char *msg, int first, int last, const uint16_t *ptr);
+void avpriv_dump_simd_u16(int line, const char *msg, int first, int last, const uint16_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint16_t *vec = &ptr[8*v];
+ fprintf(stderr, "v%02d.8h = {", v);
+ for (int i = 0; i < 8; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_s32(int line, const char *msg, int first, int last, const int32_t *ptr);
+void avpriv_dump_simd_s32(int line, const char *msg, int first, int last, const int32_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int32_t *vec = &ptr[4*v];
+ fprintf(stderr, "v%02d.4s = {", v);
+ for (int i = 0; i < 4; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u32(int line, const char *msg, int first, int last, const uint32_t *ptr);
+void avpriv_dump_simd_u32(int line, const char *msg, int first, int last, const uint32_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint32_t *vec = &ptr[4*v];
+ fprintf(stderr, "v%02d.4s = {", v);
+ for (int i = 0; i < 4; i++)
+ fprintf(stderr, "%s %u", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_s64(int line, const char *msg, int first, int last, const int64_t *ptr);
+void avpriv_dump_simd_s64(int line, const char *msg, int first, int last, const int64_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int64_t *vec = &ptr[2*v];
+ fprintf(stderr, "v%02d.2d = {", v);
+ for (int i = 0; i < 2; i++)
+ fprintf(stderr, "%s %"PRId64, i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u64(int line, const char *msg, int first, int last, const uint64_t *ptr);
+void avpriv_dump_simd_u64(int line, const char *msg, int first, int last, const uint64_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint64_t *vec = &ptr[2*v];
+ fprintf(stderr, "v%02d.2d = {", v);
+ for (int i = 0; i < 2; i++)
+ fprintf(stderr, "%s %"PRIu64, i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_f32(int line, const char *msg, int first, int last, const float *ptr);
+void avpriv_dump_simd_f32(int line, const char *msg, int first, int last, const float *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const float *vec = &ptr[4*v];
+ fprintf(stderr, "v%02d.4s = {", v);
+ for (int i = 0; i < 4; i++)
+ fprintf(stderr, "%s %f", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_f64(int line, const char *msg, int first, int last, const double *ptr);
+void avpriv_dump_simd_f64(int line, const char *msg, int first, int last, const double *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const double *vec = &ptr[2*v];
+ fprintf(stderr, "v%02d.2d = {", v);
+ for (int i = 0; i < 2; i++)
+ fprintf(stderr, "%s %f", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_gpr(int line, const char *msg, int first, int last, const size_t *ptr);
+void avpriv_dump_gpr(int line, const char *msg, int first, int last, const size_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int r = first; r <= last; r++)
+ fprintf(stderr, "x%02d = %"PRId64" (0x%"PRIx64")\n", r, (int64_t) ptr[r], (uint64_t) ptr[r]);
+ fflush(stderr);
+}
diff --git a/libavutil/arm/Makefile b/libavutil/arm/Makefile
index 2988df08ca..cc0d648276 100644
--- a/libavutil/arm/Makefile
+++ b/libavutil/arm/Makefile
@@ -1,6 +1,8 @@
OBJS += arm/cpu.o \
arm/float_dsp_init_arm.o \
+OBJS-$(CONFIG_ASM_DEBUG) += arm/asm_debug.o
+
ARMV6-OBJS-$(CONFIG_PIXELUTILS) += arm/pixelutils_armv6.o
VFP-OBJS += arm/float_dsp_init_vfp.o \
diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S
index e8a9dabbca..e61b7cdf9e 100644
--- a/libavutil/arm/asm.S
+++ b/libavutil/arm/asm.S
@@ -365,3 +365,66 @@ ELF .eabi_attribute 28, 1
#define GLUE(a, b) a ## b
#define JOIN(a, b) GLUE(a, b)
#define X(s) JOIN(EXTERN_ASM, s)
+
+
+#if CONFIG_ASM_DEBUG
+.macro call_c func, line, msg, first, last, ptr, offset
+ push {lr}
+ add lr, sp, #4
+ push {lr}
+ push {r0-r12}
+ mrs lr, cpsr
+ push {lr}
+ vpush {d16-d31}
+ vpush {d0-d15}
+ add r0, \ptr, #\offset
+ // r0 is parameter 5 to the function, pushed on the stack.
+ // r1 is unused, but pushed to keep the stack aligned to 8 bytes.
+ push {r0-r1}
+ ldr r0, =\line
+ adr r1, 777f
+ mov r2, \first
+ mov r3, \last
+ bl X(avpriv_\func)
+ pop {r0-r1}
+ vpop {d0-d15}
+ vpop {d16-d31}
+ pop {lr}
+ msr cpsr, lr
+ pop {r0-r12}
+ add sp, sp, #4
+ pop {lr}
+.endm
+
+#define CALL_C(func, msg, first, last, ptr, offset) \
+ call_c func, __LINE__, msg, first, last, ptr, offset; \
+ b 778f; \
+ 777: \
+ .asciz msg; \
+ .align 2; \
+ .ltorg; \
+ 778:
+
+#define DUMP_SIMD_S8(msg, first, last) CALL_C(dump_simd_s8, msg, first, last, sp, 0)
+#define DUMP_SIMD_U8(msg, first, last) CALL_C(dump_simd_u8, msg, first, last, sp, 0)
+#define DUMP_SIMD_S16(msg, first, last) CALL_C(dump_simd_s16, msg, first, last, sp, 0)
+#define DUMP_SIMD_U16(msg, first, last) CALL_C(dump_simd_u16, msg, first, last, sp, 0)
+#define DUMP_SIMD_S32(msg, first, last) CALL_C(dump_simd_s32, msg, first, last, sp, 0)
+#define DUMP_SIMD_U32(msg, first, last) CALL_C(dump_simd_u32, msg, first, last, sp, 0)
+#define DUMP_SIMD_S64(msg, first, last) CALL_C(dump_simd_s64, msg, first, last, sp, 0)
+#define DUMP_SIMD_U64(msg, first, last) CALL_C(dump_simd_u64, msg, first, last, sp, 0)
+#define DUMP_SIMD_F32(msg, first, last) CALL_C(dump_simd_f32, msg, first, last, sp, 0)
+#define DUMP_SIMD_F64(msg, first, last) CALL_C(dump_simd_f64, msg, first, last, sp, 0)
+#define DUMP_MEM_S8(msg, reg, n) CALL_C(dump_simd_s8, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U8(msg, reg, n) CALL_C(dump_simd_u8, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_S16(msg, reg, n) CALL_C(dump_simd_s16, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U16(msg, reg, n) CALL_C(dump_simd_u16, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_S32(msg, reg, n) CALL_C(dump_simd_s32, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U32(msg, reg, n) CALL_C(dump_simd_u32, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_S64(msg, reg, n) CALL_C(dump_simd_s64, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_U64(msg, reg, n) CALL_C(dump_simd_u64, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_F32(msg, reg, n) CALL_C(dump_simd_f32, msg, 0, n-1, reg, 0)
+#define DUMP_MEM_F64(msg, reg, n) CALL_C(dump_simd_f64, msg, 0, n-1, reg, 0)
+#define DUMP_GPR(msg, first, last) CALL_C(dump_gpr, msg, first, last, sp, 260)
+
+#endif /* CONFIG_ASM_DEBUG */
diff --git a/libavutil/arm/asm_debug.c b/libavutil/arm/asm_debug.c
new file mode 100644
index 0000000000..f9fd3d2700
--- /dev/null
+++ b/libavutil/arm/asm_debug.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright © 2019-2026, Martin Storsjo
+ * 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 "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+void avpriv_dump_simd_s8(int line, const char *msg, int first, int last, const int8_t *ptr);
+void avpriv_dump_simd_s8(int line, const char *msg, int first, int last, const int8_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int8_t *vec = &ptr[8*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 8; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u8(int line, const char *msg, int first, int last, const uint8_t *ptr);
+void avpriv_dump_simd_u8(int line, const char *msg, int first, int last, const uint8_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint8_t *vec = &ptr[8*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 8; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_s16(int line, const char *msg, int first, int last, const int16_t *ptr);
+void avpriv_dump_simd_s16(int line, const char *msg, int first, int last, const int16_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int16_t *vec = &ptr[4*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 4; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u16(int line, const char *msg, int first, int last, const uint16_t *ptr);
+void avpriv_dump_simd_u16(int line, const char *msg, int first, int last, const uint16_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint16_t *vec = &ptr[4*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 4; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_s32(int line, const char *msg, int first, int last, const int32_t *ptr);
+void avpriv_dump_simd_s32(int line, const char *msg, int first, int last, const int32_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int32_t *vec = &ptr[2*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 2; i++)
+ fprintf(stderr, "%s %d", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u32(int line, const char *msg, int first, int last, const uint32_t *ptr);
+void avpriv_dump_simd_u32(int line, const char *msg, int first, int last, const uint32_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint32_t *vec = &ptr[2*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 2; i++)
+ fprintf(stderr, "%s %u", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_s64(int line, const char *msg, int first, int last, const int64_t *ptr);
+void avpriv_dump_simd_s64(int line, const char *msg, int first, int last, const int64_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const int64_t *vec = &ptr[1*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 1; i++)
+ fprintf(stderr, "%s %"PRId64, i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_u64(int line, const char *msg, int first, int last, const uint64_t *ptr);
+void avpriv_dump_simd_u64(int line, const char *msg, int first, int last, const uint64_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const uint64_t *vec = &ptr[1*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 1; i++)
+ fprintf(stderr, "%s %"PRIu64, i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_f32(int line, const char *msg, int first, int last, const float *ptr);
+void avpriv_dump_simd_f32(int line, const char *msg, int first, int last, const float *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const float *vec = &ptr[2*v];
+ fprintf(stderr, "d%02d = {", v);
+ for (int i = 0; i < 2; i++)
+ fprintf(stderr, "%s %f", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_simd_f64(int line, const char *msg, int first, int last, const double *ptr);
+void avpriv_dump_simd_f64(int line, const char *msg, int first, int last, const double *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int v = first; v <= last; v++) {
+ const double *vec = &ptr[1*v];
+ fprintf(stderr, "v%02d = {", v);
+ for (int i = 0; i < 1; i++)
+ fprintf(stderr, "%s %f", i > 0 ? "," : "", vec[i]);
+ fprintf(stderr, " }\n");
+ }
+ fflush(stderr);
+}
+
+void avpriv_dump_gpr(int line, const char *msg, int first, int last, const size_t *ptr);
+void avpriv_dump_gpr(int line, const char *msg, int first, int last, const size_t *ptr)
+{
+ fprintf(stderr, "%d: %s:\n", line, msg);
+ for (int r = first; r <= last; r++)
+ if (r < 13)
+ fprintf(stderr, "r%02d = %"PRId32" (0x%"PRIx32")\n", r, (int32_t) ptr[r], (uint32_t) ptr[r]);
+ else
+ fprintf(stderr, "%s = %"PRId32" (0x%"PRIx32")\n", r == 13 ? "sp" : "lr", (int32_t) ptr[r], (uint32_t) ptr[r]);
+ fflush(stderr);
+}