summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/mpyfiles.rst15
-rw-r--r--mpy-cross/main.c12
-rw-r--r--py/asmrv32.h2
-rw-r--r--py/persistentcode.c19
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);