Skip to content

Commit 4308379

Browse files
committed
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 <[email protected]>
1 parent 3e2b41f commit 4308379

File tree

7 files changed

+27
-12
lines changed

7 files changed

+27
-12
lines changed

docs/reference/mpyfiles.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,14 @@ If importing an .mpy file fails then try the following:
5858
sys_mpy = sys.implementation._mpy
5959
arch = [None, 'x86', 'x64',
6060
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
61-
'xtensa', 'xtensawin', 'rv32imc', 'rv64imc'][sys_mpy >> 10]
61+
'xtensa', 'xtensawin', 'rv32imc', 'rv64imc'][(sys_mpy >> 10) & 0x0F]
6262
print('mpy version:', sys_mpy & 0xff)
6363
print('mpy sub-version:', sys_mpy >> 8 & 3)
6464
print('mpy flags:', end='')
6565
if arch:
6666
print(' -march=' + arch, end='')
67+
if (sys_mpy >> 16) != 0:
68+
print(' -march-flags=' + (sys_mpy >> 16), end='')
6769
print()
6870

6971
* Check the validity of the .mpy file by inspecting the first two bytes of

py/asmrv32.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -709,11 +709,11 @@ static inline void asm_rv32_opcode_xori(asm_rv32_t *state, mp_uint_t rd, mp_uint
709709
asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x04, rd, rs, immediate));
710710
}
711711

712+
#define MICROPY_RV32_EXTENSIONS \
713+
(MICROPY_EMIT_RV32_ZBA ? RV32_EXT_ZBA : 0)
714+
712715
static inline uint8_t asm_rv32_allowed_extensions(void) {
713-
uint8_t extensions = 0;
714-
#if MICROPY_EMIT_RV32_ZBA
715-
extensions |= RV32_EXT_ZBA;
716-
#endif
716+
uint8_t extensions = MICROPY_RV32_EXTENSIONS;
717717
#if MICROPY_DYNAMIC_COMPILER
718718
if (mp_dynamic_compiler.backend_options != NULL) {
719719
extensions |= ((asm_rv32_backend_options_t *)mp_dynamic_compiler.backend_options)->allowed_extensions;

py/modsys.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,16 @@ static const MP_DEFINE_STR_OBJ(mp_sys_implementation_machine_obj, MICROPY_BANNER
8585
MP_ROM_PTR(&mp_sys_implementation_machine_obj)
8686

8787
#if MICROPY_PERSISTENT_CODE_LOAD
88+
// Note: Adding architecture flags to _mpy will break if the flags information
89+
// takes up more bits than what is available in a small-int value.
90+
#if MICROPY_EMIT_RV32
91+
#include "py/asmrv32.h"
92+
#define MPY_FILE_ARCH_FLAGS (MICROPY_RV32_EXTENSIONS << 16)
93+
#else
94+
#define MPY_FILE_ARCH_FLAGS (0)
95+
#endif
8896
#define SYS_IMPLEMENTATION_ELEMS__MPY \
89-
, MP_ROM_INT(MPY_FILE_HEADER_INT)
97+
, MP_ROM_INT(MPY_FILE_HEADER_INT | MPY_FILE_ARCH_FLAGS)
9098
#else
9199
#define SYS_IMPLEMENTATION_ELEMS__MPY
92100
#endif

tests/feature_check/target_info.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"xtensawin",
2121
"rv32imc",
2222
"rv64imc",
23-
][sys_mpy >> 10]
23+
][(sys_mpy >> 10) & 0x0F]
24+
arch_flags = sys_mpy >> 16
2425
build = getattr(sys.implementation, "_build", "unknown")
2526
thread = getattr(sys.implementation, "_thread", None)
2627

@@ -35,4 +36,4 @@
3536
except NameError:
3637
float_prec = 0
3738

38-
print(platform, arch, build, thread, float_prec, len("α") == 1)
39+
print(platform, arch, arch_flags, build, thread, float_prec, len("α") == 1)

tests/micropython/import_mpy_native.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ def open(self, path, mode):
5454

5555
# these are the test .mpy files
5656
small_int_bits = 30
57-
valid_header = bytes([77, 6, mpy_arch, small_int_bits])
57+
valid_header = bytes([77, 6, (mpy_arch & 0x3F), small_int_bits])
5858
# fmt: off
5959
user_files = {
6060
# bad architecture (mpy_arch needed for sub-version)
61-
'/mod0.mpy': bytes([77, 6, 0xfc | mpy_arch, small_int_bits]),
61+
'/mod0.mpy': bytes([77, 6, 0xfc | (mpy_arch & 3), small_int_bits]),
6262

6363
# test loading of viper and asm
6464
'/mod1.mpy': valid_header + (

tests/micropython/import_mpy_native_gc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def open(self, path, mode):
6767
features0_file_contents[arch] = features0_file_contents[0x1006]
6868

6969
# Check that a .mpy exists for the target (ignore sub-version in lookup).
70-
sys_implementation_mpy = sys.implementation._mpy & ~(3 << 8)
70+
sys_implementation_mpy = (sys.implementation._mpy & ~(3 << 8)) & 0xFFFF
7171
if sys_implementation_mpy not in features0_file_contents:
7272
print("SKIP")
7373
raise SystemExit

tests/run-tests.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,9 @@ def detect_test_platform(pyb, args):
387387
output = run_feature_check(pyb, args, "target_info.py")
388388
if output.endswith(b"CRASH"):
389389
raise ValueError("cannot detect platform: {}".format(output))
390-
platform, arch, build, thread, float_prec, unicode = str(output, "ascii").strip().split()
390+
platform, arch, arch_flags, build, thread, float_prec, unicode = (
391+
str(output, "ascii").strip().split()
392+
)
391393
if arch == "None":
392394
arch = None
393395
inlineasm_arch = detect_inline_asm_arch(pyb, args)
@@ -400,6 +402,7 @@ def detect_test_platform(pyb, args):
400402
args.arch = arch
401403
if arch and not args.mpy_cross_flags:
402404
args.mpy_cross_flags = "-march=" + arch
405+
args.arch_flags = arch_flags
403406
args.inlineasm_arch = inlineasm_arch
404407
args.build = build
405408
args.thread = thread
@@ -410,6 +413,7 @@ def detect_test_platform(pyb, args):
410413
print("platform={}".format(platform), end="")
411414
if arch:
412415
print(" arch={}".format(arch), end="")
416+
print(" arch_flags={}".format(arch_flags), end="")
413417
if inlineasm_arch:
414418
print(" inlineasm={}".format(inlineasm_arch), end="")
415419
if thread:

0 commit comments

Comments
 (0)