summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2025-09-24 22:26:39 +0200
committerAlessandro Gatti <a.gatti@frob.it>2025-10-24 19:13:15 +0200
commit430837996b3cbb85849be92cc4d9ce98ce2a0905 (patch)
treec4415e18addffddd03e774cfb914e651b9beb7e1
parent3e2b41f8f60d39226320aad93ed3490d5add1799 (diff)
py/modsys: Add architecture flags to MicroPython metadata.
This commit adds the currently supported architecture flags value as the upper part of "sys.implementation._mpy". This had the side effect of perturbing quite a bit of testing infrastructure and invalidating documentation related to MPY files. To make the test suite run successfully and keep the documentation in sync the following changes have been made: * The target info feature check file now isolates eventual architecture flags and adds them as a separate field * The test runner now picks up the new architecture flags field, reports it to STDOUT if needed and stores it for future uses * Relevant test files for MPY files import code had to be updated to mask out the architecture flags bits in order to perform correctly * MPY file format documentation was updated to show how to mask off and properly display the architecture flags information. This works out of the box if the flag bits can fit in a smallint value once merged with the MPY file header value. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
-rw-r--r--docs/reference/mpyfiles.rst4
-rw-r--r--py/asmrv32.h8
-rw-r--r--py/modsys.c10
-rw-r--r--tests/feature_check/target_info.py5
-rw-r--r--tests/micropython/import_mpy_native.py4
-rw-r--r--tests/micropython/import_mpy_native_gc.py2
-rwxr-xr-xtests/run-tests.py6
7 files changed, 27 insertions, 12 deletions
diff --git a/docs/reference/mpyfiles.rst b/docs/reference/mpyfiles.rst
index 9687f5e46..58e45e158 100644
--- a/docs/reference/mpyfiles.rst
+++ b/docs/reference/mpyfiles.rst
@@ -58,12 +58,14 @@ If importing an .mpy file fails then try the following:
sys_mpy = sys.implementation._mpy
arch = [None, 'x86', 'x64',
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
- 'xtensa', 'xtensawin', 'rv32imc', 'rv64imc'][sys_mpy >> 10]
+ 'xtensa', 'xtensawin', 'rv32imc', 'rv64imc'][(sys_mpy >> 10) & 0x0F]
print('mpy version:', sys_mpy & 0xff)
print('mpy sub-version:', sys_mpy >> 8 & 3)
print('mpy flags:', end='')
if arch:
print(' -march=' + arch, end='')
+ if (sys_mpy >> 16) != 0:
+ print(' -march-flags=' + (sys_mpy >> 16), end='')
print()
* Check the validity of the .mpy file by inspecting the first two bytes of
diff --git a/py/asmrv32.h b/py/asmrv32.h
index 4456e6119..6f709daa1 100644
--- a/py/asmrv32.h
+++ b/py/asmrv32.h
@@ -709,11 +709,11 @@ static inline void asm_rv32_opcode_xori(asm_rv32_t *state, mp_uint_t rd, mp_uint
asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x04, rd, rs, immediate));
}
+#define MICROPY_RV32_EXTENSIONS \
+ (MICROPY_EMIT_RV32_ZBA ? RV32_EXT_ZBA : 0)
+
static inline uint8_t asm_rv32_allowed_extensions(void) {
- uint8_t extensions = 0;
- #if MICROPY_EMIT_RV32_ZBA
- extensions |= RV32_EXT_ZBA;
- #endif
+ uint8_t extensions = MICROPY_RV32_EXTENSIONS;
#if MICROPY_DYNAMIC_COMPILER
if (mp_dynamic_compiler.backend_options != NULL) {
extensions |= ((asm_rv32_backend_options_t *)mp_dynamic_compiler.backend_options)->allowed_extensions;
diff --git a/py/modsys.c b/py/modsys.c
index ef6273fc8..3dae92681 100644
--- a/py/modsys.c
+++ b/py/modsys.c
@@ -85,8 +85,16 @@ static const MP_DEFINE_STR_OBJ(mp_sys_implementation_machine_obj, MICROPY_BANNER
MP_ROM_PTR(&mp_sys_implementation_machine_obj)
#if MICROPY_PERSISTENT_CODE_LOAD
+// Note: Adding architecture flags to _mpy will break if the flags information
+// takes up more bits than what is available in a small-int value.
+#if MICROPY_EMIT_RV32
+#include "py/asmrv32.h"
+#define MPY_FILE_ARCH_FLAGS (MICROPY_RV32_EXTENSIONS << 16)
+#else
+#define MPY_FILE_ARCH_FLAGS (0)
+#endif
#define SYS_IMPLEMENTATION_ELEMS__MPY \
- , MP_ROM_INT(MPY_FILE_HEADER_INT)
+ , MP_ROM_INT(MPY_FILE_HEADER_INT | MPY_FILE_ARCH_FLAGS)
#else
#define SYS_IMPLEMENTATION_ELEMS__MPY
#endif
diff --git a/tests/feature_check/target_info.py b/tests/feature_check/target_info.py
index 35a995a15..e95530023 100644
--- a/tests/feature_check/target_info.py
+++ b/tests/feature_check/target_info.py
@@ -20,7 +20,8 @@ arch = [
"xtensawin",
"rv32imc",
"rv64imc",
-][sys_mpy >> 10]
+][(sys_mpy >> 10) & 0x0F]
+arch_flags = sys_mpy >> 16
build = getattr(sys.implementation, "_build", "unknown")
thread = getattr(sys.implementation, "_thread", None)
@@ -35,4 +36,4 @@ try:
except NameError:
float_prec = 0
-print(platform, arch, build, thread, float_prec, len("α") == 1)
+print(platform, arch, arch_flags, build, thread, float_prec, len("α") == 1)
diff --git a/tests/micropython/import_mpy_native.py b/tests/micropython/import_mpy_native.py
index 7a9bb8edd..b7908b5a6 100644
--- a/tests/micropython/import_mpy_native.py
+++ b/tests/micropython/import_mpy_native.py
@@ -54,11 +54,11 @@ class UserFS:
# these are the test .mpy files
small_int_bits = 30
-valid_header = bytes([77, 6, mpy_arch, small_int_bits])
+valid_header = bytes([77, 6, (mpy_arch & 0x3F), small_int_bits])
# fmt: off
user_files = {
# bad architecture (mpy_arch needed for sub-version)
- '/mod0.mpy': bytes([77, 6, 0xfc | mpy_arch, small_int_bits]),
+ '/mod0.mpy': bytes([77, 6, 0xfc | (mpy_arch & 3), small_int_bits]),
# test loading of viper and asm
'/mod1.mpy': valid_header + (
diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py
index 851eb3922..997e052fd 100644
--- a/tests/micropython/import_mpy_native_gc.py
+++ b/tests/micropython/import_mpy_native_gc.py
@@ -67,7 +67,7 @@ for arch in (0x1406, 0x1806, 0x1C06, 0x2006):
features0_file_contents[arch] = features0_file_contents[0x1006]
# Check that a .mpy exists for the target (ignore sub-version in lookup).
-sys_implementation_mpy = sys.implementation._mpy & ~(3 << 8)
+sys_implementation_mpy = (sys.implementation._mpy & ~(3 << 8)) & 0xFFFF
if sys_implementation_mpy not in features0_file_contents:
print("SKIP")
raise SystemExit
diff --git a/tests/run-tests.py b/tests/run-tests.py
index b55bd8e49..f184203a8 100755
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -387,7 +387,9 @@ def detect_test_platform(pyb, args):
output = run_feature_check(pyb, args, "target_info.py")
if output.endswith(b"CRASH"):
raise ValueError("cannot detect platform: {}".format(output))
- platform, arch, build, thread, float_prec, unicode = str(output, "ascii").strip().split()
+ platform, arch, arch_flags, build, thread, float_prec, unicode = (
+ str(output, "ascii").strip().split()
+ )
if arch == "None":
arch = None
inlineasm_arch = detect_inline_asm_arch(pyb, args)
@@ -400,6 +402,7 @@ def detect_test_platform(pyb, args):
args.arch = arch
if arch and not args.mpy_cross_flags:
args.mpy_cross_flags = "-march=" + arch
+ args.arch_flags = arch_flags
args.inlineasm_arch = inlineasm_arch
args.build = build
args.thread = thread
@@ -410,6 +413,7 @@ def detect_test_platform(pyb, args):
print("platform={}".format(platform), end="")
if arch:
print(" arch={}".format(arch), end="")
+ print(" arch_flags={}".format(arch_flags), end="")
if inlineasm_arch:
print(" inlineasm={}".format(inlineasm_arch), end="")
if thread: