|
34 | 34 | #include "py/persistentcode.h" |
35 | 35 | #include "py/runtime.h" |
36 | 36 | #include "py/gc.h" |
| 37 | +#include "py/parsenum.h" |
37 | 38 | #include "genhdr/mpversion.h" |
38 | 39 | #ifdef _WIN32 |
39 | 40 | #include "ports/windows/fmode.h" |
@@ -144,7 +145,7 @@ static int usage(char **argv) { |
144 | 145 | "-march=<arch> : set architecture for native emitter;\n" |
145 | 146 | " x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp,\n" |
146 | 147 | " armv7emdp, xtensa, xtensawin, rv32imc, rv64imc, host, debug\n" |
147 | | - "-march-flags=<flags> : set architecture-specific flags\n" |
| 148 | + "-march-flags=<flags> : set architecture-specific flags (can be either a dec/hex/bin value or a string)\n" |
148 | 149 | " supported flags for rv32imc: zba\n" |
149 | 150 | "\n" |
150 | 151 | "Implementation specific options:\n", argv[0] |
@@ -226,6 +227,38 @@ static char *backslash_to_forwardslash(char *path) { |
226 | 227 | return path; |
227 | 228 | } |
228 | 229 |
|
| 230 | +// This will need to be reworked in case mpy-cross needs to set more bits than |
| 231 | +// what its small int representation allows to fit in there. |
| 232 | +static bool parse_integer(const char *value, mp_uint_t *integer) { |
| 233 | + assert(value && "Attempting to parse a NULL string"); |
| 234 | + assert(integer && "Attempting to store into a NULL integer buffer"); |
| 235 | + |
| 236 | + size_t value_length = strlen(value); |
| 237 | + int base = 10; |
| 238 | + if (value_length > 2 && value[0] == '0') { |
| 239 | + if ((value[1] | 0x20) == 'b') { |
| 240 | + base = 2; |
| 241 | + } else if ((value[1] | 0x20) == 'x') { |
| 242 | + base = 16; |
| 243 | + } else { |
| 244 | + return false; |
| 245 | + } |
| 246 | + } |
| 247 | + |
| 248 | + bool valid = false; |
| 249 | + nlr_buf_t nlr; |
| 250 | + if (nlr_push(&nlr) == 0) { |
| 251 | + mp_obj_t parsed = mp_parse_num_integer(value, value_length, base, NULL); |
| 252 | + if (mp_obj_is_small_int(parsed)) { |
| 253 | + *integer = MP_OBJ_SMALL_INT_VALUE(parsed); |
| 254 | + valid = true; |
| 255 | + } |
| 256 | + nlr_pop(); |
| 257 | + } |
| 258 | + |
| 259 | + return valid; |
| 260 | +} |
| 261 | + |
229 | 262 | MP_NOINLINE int main_(int argc, char **argv) { |
230 | 263 | pre_process_options(argc, argv); |
231 | 264 |
|
@@ -378,7 +411,13 @@ MP_NOINLINE int main_(int argc, char **argv) { |
378 | 411 | #if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32 |
379 | 412 | if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC) { |
380 | 413 | mp_dynamic_compiler.backend_options = (void *)&rv32_options; |
381 | | - if (strncmp(arch_flags, "zba", sizeof("zba") - 1) == 0) { |
| 414 | + mp_uint_t raw_flags = 0; |
| 415 | + if (parse_integer(arch_flags, &raw_flags)) { |
| 416 | + if ((raw_flags & ~((mp_uint_t)RV32_EXT_ALL)) == 0) { |
| 417 | + rv32_options.allowed_extensions = raw_flags; |
| 418 | + processed = true; |
| 419 | + } |
| 420 | + } else if (strncmp(arch_flags, "zba", sizeof("zba") - 1) == 0) { |
382 | 421 | rv32_options.allowed_extensions |= RV32_EXT_ZBA; |
383 | 422 | processed = true; |
384 | 423 | } |
|
0 commit comments