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 <a.gatti@frob.it>
This commit is contained in:
Alessandro Gatti
2025-10-24 17:08:05 +02:00
parent b255224d09
commit 3e2b41f8f6

View File

@@ -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=<arch> : set architecture for native emitter;\n"
" x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp,\n"
" armv7emdp, xtensa, xtensawin, rv32imc, rv64imc, host, debug\n"
"-march-flags=<flags> : set architecture-specific flags\n"
"-march-flags=<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;
}