Skip to content

Commit 64971f1

Browse files
committed
py/persistentcode: Add architecture flags check for RV32 platforms.
This commit introduces the MPY architecture flags checking code specific for the RV32 target, currently checking for the only additional extension that is supported by the runtime: Zba. The warnings inside "mpy-cross" have also been removed since now there is a way to reject incompatible MPY files at runtime. Signed-off-by: Alessandro Gatti <[email protected]>
1 parent a6bc1cc commit 64971f1

File tree

4 files changed

+39
-9
lines changed

4 files changed

+39
-9
lines changed

docs/reference/mpyfiles.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,19 @@ If bit #6 of the header's feature flags byte is set, then a vuint containing
179179
optional architecture-specific information will follow the header. The contents
180180
of this integer depends on which native architecture the file is meant for.
181181

182-
See also ``mpy-tool.py``'s ``-march-flags`` command-line option to set this
183-
value when creating MPY files.
182+
This is currently used to store which RISC-V processor extensions the MPY file
183+
needs to operate correctly besides I, M, C, and Zicsr. Different flavours of
184+
ArmV7 are identified by their native architecture number, but reusing that
185+
mechanism would complicate things for RV32 and RV64.
186+
187+
MPY files targeting RV32 or RV64 that do not need any particular processor
188+
extensions do not need to provide a flags integer (along with setting the
189+
appropriate bit in the header). The lack of a flags value for RV32 and RV64
190+
MPY files is used to indicate that no specific extensions are needed, and saves
191+
one byte in the final output binary.
192+
193+
See also the ``-march-flags`` command-line option in both ``mpy-tool.py`` and
194+
``mpy-cross`` to set this value when creating MPY files.
184195

185196
The global qstr and constant tables
186197
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

mpy-cross/main.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ static int compile_and_save(const char *file, const char *output_file, const cha
9494
mp_compiled_module_t cm;
9595
cm.context = m_new_obj(mp_module_context_t);
9696
cm.arch_flags = 0;
97+
#if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32
98+
if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC && mp_dynamic_compiler.backend_options != NULL) {
99+
cm.arch_flags = ((asm_rv32_backend_options_t *)mp_dynamic_compiler.backend_options)->allowed_extensions;
100+
}
101+
#endif
102+
97103
mp_compile_to_raw_code(&parse_tree, source_name, false, &cm);
98104

99105
if ((output_file != NULL && strcmp(output_file, "-") == 0) ||
@@ -138,7 +144,7 @@ static int usage(char **argv) {
138144
"-march=<arch> : set architecture for native emitter;\n"
139145
" x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp,\n"
140146
" armv7emdp, xtensa, xtensawin, rv32imc, rv64imc, host, debug\n"
141-
"-march-flags=<flags> : set architecture-specific flags (OUTPUT FILE MAY NOT WORK ON ALL TARGETS!)\n"
147+
"-march-flags=<flags> : set architecture-specific flags\n"
142148
" supported flags for rv32imc: zba\n"
143149
"\n"
144150
"Implementation specific options:\n", argv[0]
@@ -382,10 +388,6 @@ MP_NOINLINE int main_(int argc, char **argv) {
382388
mp_printf(&mp_stderr_print, "unrecognised arch flags\n");
383389
exit(1);
384390
}
385-
mp_printf(&mp_stderr_print,
386-
"WARNING: Using architecture-specific flags may create a MPY file whose code won't run on all targets!\n"
387-
" Currently there are no checks in the module file loader for whether the chosen flags used to\n"
388-
" build the MPY file are compatible with the running target.\n\n");
389391
}
390392

391393
#if MICROPY_EMIT_NATIVE

py/asmrv32.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ typedef struct _asm_rv32_t {
125125
enum {
126126
RV32_EXT_NONE = 0,
127127
RV32_EXT_ZBA = 1 << 0,
128+
129+
RV32_EXT_ALL = RV32_EXT_ZBA
128130
};
129131

130132
typedef struct _asm_rv32_backend_options_t {

py/persistentcode.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ typedef struct _bytecode_prelude_t {
6363
uint code_info_size;
6464
} bytecode_prelude_t;
6565

66+
#if MICROPY_EMIT_RV32
67+
#include "py/asmrv32.h"
68+
#endif
69+
6670
#endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE
6771

6872
#if MICROPY_PERSISTENT_CODE_LOAD
@@ -485,8 +489,19 @@ void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) {
485489

486490
size_t arch_flags = 0;
487491
if (MPY_FEATURE_ARCH_FLAGS_TEST(header[2])) {
488-
(void)arch_flags;
489-
mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file"));
492+
#if MICROPY_EMIT_RV32
493+
arch_flags = read_uint(reader);
494+
495+
if (MPY_FEATURE_ARCH_TEST(MP_NATIVE_ARCH_RV32IMC)) {
496+
if ((arch_flags & (size_t)asm_rv32_allowed_extensions()) != arch_flags) {
497+
mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file"));
498+
}
499+
} else
500+
#endif
501+
{
502+
(void)arch_flags;
503+
mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file"));
504+
}
490505
}
491506

492507
size_t n_qstr = read_uint(reader);

0 commit comments

Comments
 (0)