PR #25755 opened by Martin Storsjö (mstorsjo)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25755
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25755.patch

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.




From ddc7f14b09d44ed60704c5ad6eee12eca9d35cea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <[email protected]>
Date: Fri, 22 Mar 2024 10:58:36 +0200
Subject: [PATCH] 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.
---
 configure                 |   2 +
 libavutil/Makefile        |   1 +
 libavutil/aarch64/asm.S   | 106 +++++++++++++++++++++++++
 libavutil/arm/asm.S       |  47 +++++++++++
 libavutil/arm_asm_debug.c | 161 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 317 insertions(+)
 create mode 100644 libavutil/arm_asm_debug.c

diff --git a/configure b/configure
index 2bbc7812eb3..e8c11f88be9 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/Makefile b/libavutil/Makefile
index 1f91fd5d170..76f1391a809 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -207,6 +207,7 @@ OBJS = adler32.o                                            
            \
        video_hint.o                                                     \
 
 
+OBJS-$(CONFIG_ASM_DEBUG)                += arm_asm_debug.o
 OBJS-$(CONFIG_CUDA)                     += hwcontext_cuda.o
 OBJS-$(CONFIG_D3D11VA)                  += hwcontext_d3d11va.o
 OBJS-$(CONFIG_D3D12VA)                  += hwcontext_d3d12va.o
diff --git a/libavutil/aarch64/asm.S b/libavutil/aarch64/asm.S
index 665202a8082..0ef45efade0 100644
--- a/libavutil/aarch64/asm.S
+++ b/libavutil/aarch64/asm.S
@@ -370,3 +370,109 @@ 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(ff_\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_MEM_S16(msg, reg, n)       CALL_C(dump_simd_s16, 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/arm/asm.S b/libavutil/arm/asm.S
index e8a9dabbca5..86c9fe395ba 100644
--- a/libavutil/arm/asm.S
+++ b/libavutil/arm/asm.S
@@ -365,3 +365,50 @@ 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}
+        mov             lr,  sp
+        push            {lr}
+        push            {r0-r12}
+        mrs             lr,  cpsr
+        push            {lr}
+        vpush           {d16-d31}
+        vpush           {d0-d15}
+        add             r0,  \ptr, #\offset
+        push            {r0}
+        ldr             r0,  =\line
+        adr             r1,  777f
+        mov             r2,  \first
+        mov             r3,  \last
+        bl              X(ff_\func)
+        pop             {r0}
+        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_MEM_S16(msg, reg, n)       CALL_C(dump_simd_s16, 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 00000000000..5c1c90fc2c5
--- /dev/null
+++ b/libavutil/arm_asm_debug.c
@@ -0,0 +1,161 @@
+/*
+ * 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 ff_dump_simd_s8(int line, const char *msg, int first, int last, const 
int8_t *ptr);
+void ff_dump_simd_s8(int line, const char *msg, int first, int last, const 
int8_t *ptr) {
+    fprintf(stderr, "%d: %s:\n", line, msg);
+#if ARCH_AARCH64
+    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");
+    }
+#elif ARCH_ARM
+    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");
+    }
+#endif
+    fflush(stderr);
+}
+
+void ff_dump_simd_u8(int line, const char *msg, int first, int last, const 
uint8_t *ptr);
+void ff_dump_simd_u8(int line, const char *msg, int first, int last, const 
uint8_t *ptr) {
+    fprintf(stderr, "%d: %s:\n", line, msg);
+#if ARCH_AARCH64
+    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");
+    }
+#elif ARCH_ARM
+    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");
+    }
+#endif
+    fflush(stderr);
+}
+
+void ff_dump_simd_s16(int line, const char *msg, int first, int last, const 
int16_t *ptr);
+void ff_dump_simd_s16(int line, const char *msg, int first, int last, const 
int16_t *ptr) {
+    fprintf(stderr, "%d: %s:\n", line, msg);
+#if ARCH_AARCH64
+    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");
+    }
+#elif ARCH_ARM
+    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");
+    }
+#endif
+    fflush(stderr);
+}
+
+void ff_dump_simd_u16(int line, const char *msg, int first, int last, const 
uint16_t *ptr);
+void ff_dump_simd_u16(int line, const char *msg, int first, int last, const 
uint16_t *ptr) {
+    fprintf(stderr, "%d: %s:\n", line, msg);
+#if ARCH_AARCH64
+    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");
+    }
+#elif ARCH_ARM
+    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");
+    }
+#endif
+    fflush(stderr);
+}
+
+void ff_dump_simd_s32(int line, const char *msg, int first, int last, const 
int32_t *ptr);
+void ff_dump_simd_s32(int line, const char *msg, int first, int last, const 
int32_t *ptr) {
+    fprintf(stderr, "%d: %s:\n", line, msg);
+#if ARCH_AARCH64
+    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");
+    }
+#elif ARCH_ARM
+    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");
+    }
+#endif
+    fflush(stderr);
+}
+
+void ff_dump_gpr(int line, const char *msg, int first, int last, const size_t 
*ptr);
+void ff_dump_gpr(int line, const char *msg, int first, int last, const size_t 
*ptr) {
+    fprintf(stderr, "%d: %s:\n", line, msg);
+#if ARCH_AARCH64
+    for (int r = first; r <= last; r++)
+        fprintf(stderr, "x%02d = %"PRId64" (0x%"PRIx64")\n", r, (int64_t) 
ptr[r], (uint64_t) ptr[r]);
+#elif ARCH_ARM
+    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]);
+#endif
+    fflush(stderr);
+}
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to