tests/run-tests.py: Detect inlineasm support and add tests if needed.

This commit implements a method to detect at runtime if inline assembler
support is enabled, and if so which platform it targets.

This allows clean test runs even on modified version of ARM-based ports
where inline assembler support is disabled, running inline assembler tests
on ports that have such feature not enabled by default and manually
enabled, and allows to always run the correct inlineasm tests for ports
that support more than one architecture (esp32, qemu, rp2).

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
Alessandro Gatti
2024-11-20 11:55:54 +01:00
committed by Damien George
parent 24482a93ef
commit 931a768f55
12 changed files with 68 additions and 36 deletions

View File

@@ -11,6 +11,3 @@ LDSCRIPT = mcu/arm/nrf51.ld
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb1.o SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb1.o
MPY_CROSS_FLAGS += -march=armv7m MPY_CROSS_FLAGS += -march=armv7m
# These RV32 tests don't run on Thumb, so exclude them.
RUN_TESTS_ARGS = --exclude 'inlineasm/rv32'

View File

@@ -10,6 +10,3 @@ LDSCRIPT = mcu/arm/mps2.ld
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o
MPY_CROSS_FLAGS += -march=armv7m MPY_CROSS_FLAGS += -march=armv7m
# These RV32 tests don't run on Thumb, so exclude them.
RUN_TESTS_ARGS = --exclude 'inlineasm/rv32'

View File

@@ -10,6 +10,3 @@ LDSCRIPT = mcu/arm/stm32.ld
SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o
MPY_CROSS_FLAGS += -march=armv7m MPY_CROSS_FLAGS += -march=armv7m
# These RV32 tests don't run on Thumb, so exclude them.
RUN_TESTS_ARGS = --exclude 'inlineasm/rv32'

View File

@@ -16,4 +16,4 @@ SRC_BOARD_O = shared/runtime/gchelper_generic.o
MPY_CROSS_FLAGS += -march=armv6 MPY_CROSS_FLAGS += -march=armv6
# These tests don't work on Cortex-A9, so exclude them. # These tests don't work on Cortex-A9, so exclude them.
RUN_TESTS_ARGS = --exclude 'inlineasm/rv32|inlineasm/thumb/(asmdiv|asmspecialregs).py' RUN_TESTS_ARGS = --exclude 'inlineasm/thumb/(asmdiv|asmspecialregs).py'

View File

@@ -10,7 +10,4 @@ SRC_BOARD_O += shared/runtime/gchelper_native.o shared/runtime/gchelper_rv32i.o
MPY_CROSS_FLAGS += -march=rv32imc MPY_CROSS_FLAGS += -march=rv32imc
# These Thumb tests don't run on RV32, so exclude them.
RUN_TESTS_ARGS = --exclude 'inlineasm/thumb'
RUN_NATMODTESTS_ARGS = --arch rv32imc RUN_NATMODTESTS_ARGS = --arch rv32imc

View File

@@ -0,0 +1,9 @@
# check if RISC-V 32 inline asm is supported
@micropython.asm_rv32
def f():
add(a0, a0, a0)
print("rv32")

View File

@@ -0,0 +1 @@
rv32

View File

@@ -0,0 +1,9 @@
# check if Thumb inline asm is supported
@micropython.asm_thumb
def f():
nop()
print("thumb")

View File

@@ -0,0 +1 @@
thumb

View File

@@ -0,0 +1,9 @@
# check if Xtensa inline asm is supported
@micropython.asm_xtensa
def f():
ret_n()
print("xtensa")

View File

@@ -0,0 +1 @@
xtensa

View File

@@ -232,6 +232,14 @@ def get_test_instance(test_instance, baudrate, user, password):
return pyb return pyb
def detect_inline_asm_arch(pyb, args):
for arch in ("rv32", "thumb", "xtensa"):
output = run_feature_check(pyb, args, "inlineasm_{}.py".format(arch))
if output.strip() == arch.encode():
return arch
return None
def detect_test_platform(pyb, args): def detect_test_platform(pyb, args):
# Run a script to detect various bits of information about the target test instance. # Run a script to detect various bits of information about the target test instance.
output = run_feature_check(pyb, args, "target_info.py") output = run_feature_check(pyb, args, "target_info.py")
@@ -240,15 +248,19 @@ def detect_test_platform(pyb, args):
platform, arch = str(output, "ascii").strip().split() platform, arch = str(output, "ascii").strip().split()
if arch == "None": if arch == "None":
arch = None arch = None
inlineasm_arch = detect_inline_asm_arch(pyb, args)
args.platform = platform args.platform = platform
args.arch = arch args.arch = arch
if arch and not args.mpy_cross_flags: if arch and not args.mpy_cross_flags:
args.mpy_cross_flags = "-march=" + arch args.mpy_cross_flags = "-march=" + arch
args.inlineasm_arch = inlineasm_arch
print("platform={}".format(platform), end="") print("platform={}".format(platform), end="")
if arch: if arch:
print(" arch={}".format(arch), end="") print(" arch={}".format(arch), end="")
if inlineasm_arch:
print(" inlineasm={}".format(inlineasm_arch), end="")
print() print()
@@ -601,6 +613,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
skip_io_module = False skip_io_module = False
skip_fstring = False skip_fstring = False
skip_endian = False skip_endian = False
skip_inlineasm = False
has_complex = True has_complex = True
has_coverage = False has_coverage = False
@@ -661,6 +674,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
if output != b"a=1\n": if output != b"a=1\n":
skip_fstring = True skip_fstring = True
if args.inlineasm_arch == "thumb":
# Check if @micropython.asm_thumb supports Thumb2 instructions, and skip such tests if it doesn't # Check if @micropython.asm_thumb supports Thumb2 instructions, and skip such tests if it doesn't
output = run_feature_check(pyb, args, "inlineasm_thumb2.py") output = run_feature_check(pyb, args, "inlineasm_thumb2.py")
if output != b"thumb2\n": if output != b"thumb2\n":
@@ -699,6 +713,8 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
) )
skip_endian = upy_byteorder != cpy_byteorder skip_endian = upy_byteorder != cpy_byteorder
skip_inlineasm = args.inlineasm_arch is None
# These tests don't test slice explicitly but rather use it to perform the test # These tests don't test slice explicitly but rather use it to perform the test
misc_slice_tests = ( misc_slice_tests = (
"builtin_range", "builtin_range",
@@ -852,6 +868,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
is_const = test_name.startswith("const") is_const = test_name.startswith("const")
is_io_module = test_name.startswith("io_") is_io_module = test_name.startswith("io_")
is_fstring = test_name.startswith("string_fstring") is_fstring = test_name.startswith("string_fstring")
is_inlineasm = test_name.startswith("asm")
skip_it = test_file in skip_tests skip_it = test_file in skip_tests
skip_it |= skip_native and is_native skip_it |= skip_native and is_native
@@ -865,6 +882,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1):
skip_it |= skip_revops and "reverse_op" in test_name skip_it |= skip_revops and "reverse_op" in test_name
skip_it |= skip_io_module and is_io_module skip_it |= skip_io_module and is_io_module
skip_it |= skip_fstring and is_fstring skip_it |= skip_fstring and is_fstring
skip_it |= skip_inlineasm and is_inlineasm
if skip_it: if skip_it:
print("skip ", test_file) print("skip ", test_file)
@@ -1213,17 +1231,17 @@ the last matching regex is used:
"misc", "misc",
"extmod", "extmod",
) )
if args.inlineasm_arch is not None:
test_dirs += ("inlineasm/{}".format(args.inlineasm_arch),)
if args.platform == "pyboard": if args.platform == "pyboard":
# run pyboard tests # run pyboard tests
test_dirs += ("float", "stress", "inlineasm/thumb", "ports/stm32") test_dirs += ("float", "stress", "ports/stm32")
elif args.platform == "mimxrt": elif args.platform == "mimxrt":
test_dirs += ("float", "stress", "inlineasm/thumb") test_dirs += ("float", "stress")
elif args.platform == "renesas-ra": elif args.platform == "renesas-ra":
test_dirs += ("float", "inlineasm/thumb", "ports/renesas-ra") test_dirs += ("float", "ports/renesas-ra")
elif args.platform == "rp2": elif args.platform == "rp2":
test_dirs += ("float", "stress", "thread", "ports/rp2") test_dirs += ("float", "stress", "thread", "ports/rp2")
if "arm" in args.mpy_cross_flags:
test_dirs += ("inlineasm/thumb",)
elif args.platform == "esp32": elif args.platform == "esp32":
test_dirs += ("float", "stress", "thread") test_dirs += ("float", "stress", "thread")
elif args.platform in ("esp8266", "minimal", "samd", "nrf"): elif args.platform in ("esp8266", "minimal", "samd", "nrf"):
@@ -1247,10 +1265,6 @@ the last matching regex is used:
"float", "float",
"ports/qemu", "ports/qemu",
) )
if args.arch == "rv32imc":
test_dirs += ("inlineasm/rv32",)
else:
test_dirs += ("inlineasm/thumb",)
elif args.platform == "webassembly": elif args.platform == "webassembly":
test_dirs += ("float", "ports/webassembly") test_dirs += ("float", "ports/webassembly")
else: else: