diff options
| -rw-r--r-- | docs/reference/mpyfiles.rst | 15 | ||||
| -rw-r--r-- | mpy-cross/main.c | 12 | ||||
| -rw-r--r-- | py/asmrv32.h | 2 | ||||
| -rw-r--r-- | py/persistentcode.c | 19 |
4 files changed, 39 insertions, 9 deletions
diff --git a/docs/reference/mpyfiles.rst b/docs/reference/mpyfiles.rst index b2d552d09..9687f5e46 100644 --- a/docs/reference/mpyfiles.rst +++ b/docs/reference/mpyfiles.rst @@ -179,8 +179,19 @@ If bit #6 of the header's feature flags byte is set, then a vuint containing optional architecture-specific information will follow the header. The contents of this integer depends on which native architecture the file is meant for. -See also ``mpy-tool.py``'s ``-march-flags`` command-line option to set this -value when creating MPY files. +This is currently used to store which RISC-V processor extensions the MPY file +needs to operate correctly besides I, M, C, and Zicsr. Different flavours of +ArmV7 are identified by their native architecture number, but reusing that +mechanism would complicate things for RV32 and RV64. + +MPY files targeting RV32 or RV64 that do not need any particular processor +extensions do not need to provide a flags integer (along with setting the +appropriate bit in the header). The lack of a flags value for RV32 and RV64 +MPY files is used to indicate that no specific extensions are needed, and saves +one byte in the final output binary. + +See also the ``-march-flags`` command-line option in both ``mpy-tool.py`` and +``mpy-cross`` to set this value when creating MPY files. The global qstr and constant tables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 0415eb664..246390383 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -94,6 +94,12 @@ static int compile_and_save(const char *file, const char *output_file, const cha mp_compiled_module_t cm; cm.context = m_new_obj(mp_module_context_t); cm.arch_flags = 0; + #if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32 + if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC && mp_dynamic_compiler.backend_options != NULL) { + cm.arch_flags = ((asm_rv32_backend_options_t *)mp_dynamic_compiler.backend_options)->allowed_extensions; + } + #endif + mp_compile_to_raw_code(&parse_tree, source_name, false, &cm); if ((output_file != NULL && strcmp(output_file, "-") == 0) || @@ -138,7 +144,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 (OUTPUT FILE MAY NOT WORK ON ALL TARGETS!)\n" + "-march-flags=<flags> : set architecture-specific flags\n" " supported flags for rv32imc: zba\n" "\n" "Implementation specific options:\n", argv[0] @@ -382,10 +388,6 @@ MP_NOINLINE int main_(int argc, char **argv) { mp_printf(&mp_stderr_print, "unrecognised arch flags\n"); exit(1); } - mp_printf(&mp_stderr_print, - "WARNING: Using architecture-specific flags may create a MPY file whose code won't run on all targets!\n" - " Currently there are no checks in the module file loader for whether the chosen flags used to\n" - " build the MPY file are compatible with the running target.\n\n"); } #if MICROPY_EMIT_NATIVE diff --git a/py/asmrv32.h b/py/asmrv32.h index 27a08cf9f..4456e6119 100644 --- a/py/asmrv32.h +++ b/py/asmrv32.h @@ -125,6 +125,8 @@ typedef struct _asm_rv32_t { enum { RV32_EXT_NONE = 0, RV32_EXT_ZBA = 1 << 0, + + RV32_EXT_ALL = RV32_EXT_ZBA }; typedef struct _asm_rv32_backend_options_t { diff --git a/py/persistentcode.c b/py/persistentcode.c index 7d71cfd98..b12c10074 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -63,6 +63,10 @@ typedef struct _bytecode_prelude_t { uint code_info_size; } bytecode_prelude_t; +#if MICROPY_EMIT_RV32 +#include "py/asmrv32.h" +#endif + #endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_LOAD @@ -485,8 +489,19 @@ void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) { size_t arch_flags = 0; if (MPY_FEATURE_ARCH_FLAGS_TEST(header[2])) { - (void)arch_flags; - mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); + #if MICROPY_EMIT_RV32 + arch_flags = read_uint(reader); + + if (MPY_FEATURE_ARCH_TEST(MP_NATIVE_ARCH_RV32IMC)) { + if ((arch_flags & (size_t)asm_rv32_allowed_extensions()) != arch_flags) { + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); + } + } else + #endif + { + (void)arch_flags; + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); + } } size_t n_qstr = read_uint(reader); |
