mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-11-06 05:17:42 +00:00
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>
This commit is contained in:
1 parent
5104bf0245
commit
372d0019b3
1 file changed
+93
-1
@@ -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, ¯os);
|
||||
if (ret >= 0)
|
||||
ret = write_file(nasm_path, macros);
|
||||
av_free(macros);
|
||||
}
|
||||
|
||||
free_uops(&root);
|
||||
return ret;
|
||||
}
|
||||
Reference in new issue
Block a user