From 3e2b41f8f60d39226320aad93ed3490d5add1799 Mon Sep 17 00:00:00 2001 From: Alessandro Gatti Date: Fri, 24 Oct 2025 17:08:05 +0200 Subject: [PATCH] mpy-cross/main: Parse raw integer arch flags values too. This commit extends "mpy-cross"'s parsing of the architecture flags value command line, allowing raw integer values as well as flag strings. Integers can be represented as either decimal, binary, or hexadecimal values, using the usual C language prefixes to mark non-base 10 values. Signed-off-by: Alessandro Gatti --- mpy-cross/main.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 246390383a..38190671c6 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -34,6 +34,7 @@ #include "py/persistentcode.h" #include "py/runtime.h" #include "py/gc.h" +#include "py/parsenum.h" #include "genhdr/mpversion.h" #ifdef _WIN32 #include "ports/windows/fmode.h" @@ -144,7 +145,7 @@ static int usage(char **argv) { "-march= : set architecture for native emitter;\n" " x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp,\n" " armv7emdp, xtensa, xtensawin, rv32imc, rv64imc, host, debug\n" - "-march-flags= : set architecture-specific flags\n" + "-march-flags= : set architecture-specific flags (can be either a dec/hex/bin value or a string)\n" " supported flags for rv32imc: zba\n" "\n" "Implementation specific options:\n", argv[0] @@ -226,6 +227,38 @@ static char *backslash_to_forwardslash(char *path) { return path; } +// This will need to be reworked in case mpy-cross needs to set more bits than +// what its small int representation allows to fit in there. +static bool parse_integer(const char *value, mp_uint_t *integer) { + assert(value && "Attempting to parse a NULL string"); + assert(integer && "Attempting to store into a NULL integer buffer"); + + size_t value_length = strlen(value); + int base = 10; + if (value_length > 2 && value[0] == '0') { + if ((value[1] | 0x20) == 'b') { + base = 2; + } else if ((value[1] | 0x20) == 'x') { + base = 16; + } else { + return false; + } + } + + bool valid = false; + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t parsed = mp_parse_num_integer(value, value_length, base, NULL); + if (mp_obj_is_small_int(parsed)) { + *integer = MP_OBJ_SMALL_INT_VALUE(parsed); + valid = true; + } + nlr_pop(); + } + + return valid; +} + MP_NOINLINE int main_(int argc, char **argv) { pre_process_options(argc, argv); @@ -378,7 +411,13 @@ MP_NOINLINE int main_(int argc, char **argv) { #if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32 if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC) { mp_dynamic_compiler.backend_options = (void *)&rv32_options; - if (strncmp(arch_flags, "zba", sizeof("zba") - 1) == 0) { + mp_uint_t raw_flags = 0; + if (parse_integer(arch_flags, &raw_flags)) { + if ((raw_flags & ~((mp_uint_t)RV32_EXT_ALL)) == 0) { + rv32_options.allowed_extensions = raw_flags; + processed = true; + } + } else if (strncmp(arch_flags, "zba", sizeof("zba") - 1) == 0) { rv32_options.allowed_extensions |= RV32_EXT_ZBA; processed = true; }