summaryrefslogtreecommitdiff
path: root/tests/inlineasm/rv32/asmsanity.py
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2024-08-25 16:28:35 +0200
committerDamien George <damien@micropython.org>2025-01-02 11:49:10 +1100
commit268acb714dd79fa5eeeb82c1fca022bc4ea126b7 (patch)
tree428ed75070ee89847fd5087095e3d7331d5f9b26 /tests/inlineasm/rv32/asmsanity.py
parent3044233ea3726e9d8727d8f6a76f32c48e6fae5e (diff)
py/emitinlinerv32: Add inline assembler support for RV32.
This commit adds support for writing inline assembler functions when targeting a RV32IMC processor. Given that this takes up a bit of rodata space due to its large instruction decoding table and its extensive error messages, it is enabled by default only on offline targets such as mpy-cross and the qemu port. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Diffstat (limited to 'tests/inlineasm/rv32/asmsanity.py')
-rw-r--r--tests/inlineasm/rv32/asmsanity.py204
1 files changed, 204 insertions, 0 deletions
diff --git a/tests/inlineasm/rv32/asmsanity.py b/tests/inlineasm/rv32/asmsanity.py
new file mode 100644
index 000000000..1a16d3504
--- /dev/null
+++ b/tests/inlineasm/rv32/asmsanity.py
@@ -0,0 +1,204 @@
+TEMPLATE3 = """
+@micropython.asm_rv32
+def f():
+ {}({}, {}, {})
+"""
+
+TEMPLATE2 = """
+@micropython.asm_rv32
+def f():
+ {}({}, {})
+"""
+
+TEMPLATE1 = """
+@micropython.asm_rv32
+def f():
+ {}({})
+"""
+
+
+REGISTERS = [
+ "zero",
+ "s0",
+ "s1",
+ "s2",
+ "s3",
+ "s4",
+ "s5",
+ "s6",
+ "s7",
+ "s8",
+ "s9",
+ "s10",
+ "s11",
+ "a0",
+ "a1",
+ "a2",
+ "a3",
+ "a4",
+ "a5",
+ "a6",
+ "a7",
+ "tp",
+ "gp",
+ "sp",
+ "ra",
+ "t0",
+ "t1",
+ "t2",
+ "t3",
+ "t4",
+ "t5",
+ "t6",
+ "x0",
+ "x1",
+ "x2",
+ "x3",
+ "x4",
+ "x5",
+ "x6",
+ "x7",
+ "x8",
+ "x9",
+ "x10",
+ "x11",
+ "x12",
+ "x13",
+ "x14",
+ "x15",
+ "x16",
+ "x17",
+ "x18",
+ "x19",
+ "x20",
+ "x21",
+ "x22",
+ "x23",
+ "x24",
+ "x25",
+ "x26",
+ "x27",
+ "x28",
+ "x29",
+ "x30",
+ "x31",
+]
+
+
+def harness(opcode, fragment, tag):
+ try:
+ exec(fragment)
+ except SyntaxError:
+ print(tag, opcode)
+
+
+for opcode in ("slli", "srli", "srai"):
+ harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", -1), "-")
+ harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", 33), "+")
+
+for opcode in ("c_slli", "c_srli", "c_srai"):
+ harness(opcode, TEMPLATE2.format(opcode, "a0", -1), "-")
+ harness(opcode, TEMPLATE2.format(opcode, "a0", 33), "+")
+
+harness("c_slli", TEMPLATE2.format("c_slli", "zero", 0), "0")
+harness("c_slli", TEMPLATE2.format("c_slli", "x0", 0), "0")
+
+for opcode in ("c_srli", "c_srai"):
+ for register in REGISTERS:
+ harness(opcode, TEMPLATE2.format(opcode, register, 0), register)
+
+for opcode in ("c_mv", "c_add"):
+ harness(opcode, TEMPLATE2.format(opcode, "a0", "zero"), "0l")
+ harness(opcode, TEMPLATE2.format(opcode, "zero", "a0"), "0r")
+ harness(opcode, TEMPLATE2.format(opcode, "zero", "zero"), "0b")
+
+harness("c_jr", TEMPLATE1.format("c_jr", "zero"), "0")
+
+for opcode in ("addi", "andi", "ori", "slti", "sltiu", "xori"):
+ harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", 0x7FF), ">=s")
+ harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", 0x800), ">s")
+ harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", -2048), "<=s")
+ harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", -2049), "<s")
+
+for opcode in ("lb", "lbu", "lh", "lhu", "lw", "sb", "sh", "sw"):
+ TEMPLATE = """
+@micropython.asm_rv32
+def f():
+ {}(a0, {}(a0))
+"""
+ harness(opcode, TEMPLATE.format(opcode, 0x7FF), ">=s")
+ harness(opcode, TEMPLATE.format(opcode, 0x800), ">s")
+ harness(opcode, TEMPLATE.format(opcode, -2048), "<=s")
+ harness(opcode, TEMPLATE.format(opcode, -2049), "<s")
+
+harness("c_addi", TEMPLATE2.format("c_andi", "zero", 0), "00")
+harness("c_addi", TEMPLATE2.format("c_andi", "zero", 512), ">0")
+harness("c_addi", TEMPLATE2.format("c_andi", "zero", -512), "<0")
+harness("c_addi", TEMPLATE2.format("c_andi", "s0", 0), "s0")
+harness("c_addi", TEMPLATE2.format("c_andi", "s0", -100), "<s")
+harness("c_addi", TEMPLATE2.format("c_andi", "s0", 100), ">s")
+
+harness("c_andi", TEMPLATE2.format("c_andi", "zero", 0), "00")
+harness("c_andi", TEMPLATE2.format("c_andi", "zero", 512), ">0")
+harness("c_andi", TEMPLATE2.format("c_andi", "zero", -512), "<0")
+harness("c_andi", TEMPLATE2.format("c_andi", "s0", 0), "s0")
+harness("c_andi", TEMPLATE2.format("c_andi", "s0", -100), "<s")
+harness("c_andi", TEMPLATE2.format("c_andi", "s0", 100), ">s")
+
+C_REGISTERS = (
+ "a0",
+ "a1",
+ "a2",
+ "a3",
+ "a4",
+ "a5",
+ "s0",
+ "s1",
+ "x8",
+ "x9",
+ "x10",
+ "x11",
+ "x12",
+ "x13",
+ "x14",
+ "x15",
+)
+
+for opcode in ("c_and", "c_or", "c_xor"):
+ for source in REGISTERS:
+ for destination in REGISTERS:
+ if source in C_REGISTERS and destination in C_REGISTERS:
+ try:
+ exec(
+ """
+@micropython.asm_rv32
+def f():
+ {}({}, {})
+""".format(opcode, source, destination)
+ )
+ except SyntaxError:
+ print(source, destination, opcode)
+ else:
+ try:
+ exec(
+ """
+@micropython.asm_rv32
+def f():
+ {}({}, {})
+""".format(opcode, source, destination)
+ )
+ print(source, destination, opcode)
+ except SyntaxError:
+ pass
+ print(opcode)
+
+for opcode in ("c_lw", "c_sw"):
+ TEMPLATE = """
+@micropython.asm_rv32
+def f():
+ {}(a0, {}(a0))
+"""
+ harness(opcode, TEMPLATE.format(opcode, 60), ">=s")
+ harness(opcode, TEMPLATE.format(opcode, 61), ">s")
+ harness(opcode, TEMPLATE.format(opcode, -60), "<=s")
+ harness(opcode, TEMPLATE.format(opcode, -61), "<s")