Commit 372d0019b3 for ffmpeg

commit 372d0019b34c44d814e1e27d5eaaacca337c0347
Author: Niklas Haas <git@haasn.dev>
Date:   Thu Oct 22 19:55:59 2026 +0200

    swscale/uops_macros_gen: add -nasm option

    Additionally writes the uops as NASM macros to the given file, as one
    DECL_<TYPE>_<UOP> macro per uop group invoking DECL_OP for each uop. This is
    an alternative to running the C preprocessor over the C macros.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Signed-off-by: Niklas Haas <git@haasn.dev>

diff --git a/libswscale/uops_macros_gen.c b/libswscale/uops_macros_gen.c
index b3286f2530..7ac33e8dc7 100644
--- a/libswscale/uops_macros_gen.c
+++ b/libswscale/uops_macros_gen.c
@@ -16,7 +16,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */

+#include <errno.h>
 #include <stdbool.h>
+#include <stdio.h>
 #include <string.h>

 #ifdef _WIN32
@@ -150,6 +152,19 @@ static int generate_entry_args(void *opaque, void *key)
     return 0;
 }

+static int generate_entry_nasm(void *opaque, void *key)
+{
+    const SwsUOp *ref = opaque;
+    const SwsUOp *uop = key;
+    AVBPrint *bp = ref->data.opaque;
+    char name[SWS_UOP_NAME_MAX];
+    ff_sws_uop_name(uop, name);
+    av_bprintf(bp, "\n    DECL_OP %%1, %-40s, %-13s, %-24s, 0x%x",
+               name, pixel_types[uop->type].full, uop_names[uop->uop].full, uop->mask);
+    print_params(bp, uop, false);
+    return 0;
+}
+
 struct EnumPriv {
     struct AVTreeNode *root;
     AVMutex lock;
@@ -339,6 +354,8 @@ fail:
     return ret;
 }

+#define BPRINT_STR(str) av_bprint_append_data(bp, str, strlen(str))
+
 /**
  * Generate a set of boilerplate C preprocessor macros for describing and
  * programmatically iterating over all SwsUOps in the tree at `root`.
@@ -351,7 +368,6 @@ static int print_macros(struct AVTreeNode *root, char **out_str)
     AVBPrint bprint, *const bp = &bprint;
     av_bprint_init(bp, 0, AV_BPRINT_SIZE_UNLIMITED);

-    #define BPRINT_STR(str) av_bprint_append_data(bp, str, strlen(str))
     BPRINT_STR(
 "/**\n"
 " * This file is automatically generated. Do not edit manually.\n"
@@ -393,12 +409,80 @@ static int print_macros(struct AVTreeNode *root, char **out_str)
     return av_bprint_finalize(bp, out_str);
 }

+/**
+ * Generate the equivalent NASM macros, as one DECL_<TYPE>_<UOP> macro per
+ * uop group. Same return semantics as print_macros().
+ */
+static int print_nasm_macros(struct AVTreeNode *root, char **out_str)
+{
+    AVBPrint bprint, *const bp = &bprint;
+    av_bprint_init(bp, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    BPRINT_STR(
+";******************************************************************************\n"
+";* This file is automatically generated. Do not edit manually.\n"
+";* To regenerate, run: make fate-sws-uops-macros GEN=1\n"
+";*\n"
+";* Boilerplate helper macros, for template-based backends. Invoking\n"
+";* DECL_<TYPE>_<UOP> MACRO will instantiate, for every matching uop:\n"
+";*   DECL_OP MACRO, NAME, TYPE, UOP, MASK, [PARAMS]\n"
+";* with parameters in struct order.\n"
+";******************************************************************************");
+
+    SwsUOp key = { .data.opaque = bp };
+    for (key.type = SWS_PIXEL_NONE + 1; key.type < SWS_PIXEL_TYPE_NB; key.type++) {
+        for (key.uop = SWS_UOP_INVALID + 1; key.uop < SWS_UOP_TYPE_NB; key.uop++) {
+            const char *macro  = uop_names[key.uop].full + sizeof("SWS_UOP_") - 1;
+            const char *prefix = pixel_types[key.type].prefix;
+            av_bprintf(bp, "\n\n%%macro DECL_%s%s 1", prefix, macro);
+            av_tree_enumerate(root, &key, enum_type, generate_entry_nasm);
+            av_bprintf(bp, "\n%%endmacro");
+        }
+    }
+
+    return av_bprint_finalize(bp, out_str);
+}
+
+static int write_file(const char *path, const char *str)
+{
+    FILE *out = fopen(path, "wb");
+    if (!out) {
+        int ret = AVERROR(errno);
+        fprintf(stderr, "Failed to open %s: %s\n", path, av_err2str(ret));
+        return ret;
+    }
+
+    int ret = 0;
+    if (fputs(str, out) < 0 || fputc('\n', out) < 0)
+        ret = AVERROR(EIO);
+    if (fclose(out) != 0 && ret >= 0)
+        ret = AVERROR(errno);
+    return ret;
+}
+
+static int usage(void)
+{
+    fprintf(stderr, "Usage: uops_macros_gen [-nasm FILE]\n"
+                    "Writes C macros to stdout, and optionally NASM macros to FILE\n");
+    return 1;
+}
+
 int main(int argc, char **argv)
 {
 #ifdef _WIN32
     _setmode(_fileno(stdout), _O_BINARY);
 #endif

+    const char *nasm_path = NULL;
+    for (int i = 1; i < argc; i += 2) {
+        if (i + 1 >= argc)
+            return usage();
+        if (!strcmp(argv[i], "-nasm"))
+            nasm_path = argv[i + 1];
+        else
+            return usage();
+    }
+
     struct AVTreeNode *root = NULL;
     int ret = collect_uops(&root);
     if (ret < 0)
@@ -409,6 +493,14 @@ int main(int argc, char **argv)
     if (ret >= 0)
         puts(macros);
     av_free(macros);
+
+    if (ret >= 0 && nasm_path) {
+        ret = print_nasm_macros(root, &macros);
+        if (ret >= 0)
+            ret = write_file(nasm_path, macros);
+        av_free(macros);
+    }
+
     free_uops(&root);
     return ret;
 }