tests/micropython/viper_ptr: Add tests for arch edge cases.

This commit adds a series of test cases to exercise the Viper code
generator load/store emitting capabilities on certain boundary
conditions.

The new test cases check whether the emitted load/store code performs
correctly when dealing with specific memory offsets, which trigger
specific code generation sequences on different architectures.

Right now the cases are for unsigned offsets whose bitmasks span up to
5, 8, and 12 bits (respectively Arm/Thumb, Xtensa, RV32).

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
Alessandro Gatti
2025-05-07 20:31:38 +02:00
parent e66a6022e2
commit 2260fe0828
12 changed files with 265 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
# Test boundary conditions for various architectures
GET_TEMPLATE = """
@micropython.viper
def get{off}(src: ptr16) -> int:
return src[{off}]
print(b[{off} * 2:({off} + 1) * 2])
"""
@micropython.viper
def get_index(src: ptr16, i: int) -> int:
return src[i]
b = bytearray(5000)
b[28:38] = b"0123456789"
b[252:262] = b"ABCDEFGHIJ"
b[4092:4102] = b"KLMNOPQRST"
for pre, idx, post in (15, 16, 17), (127, 128, 129), (2047, 2048, 2049):
print(get_index(b, pre), get_index(b, idx), get_index(b, post))
exec(GET_TEMPLATE.format(off=pre))
exec(GET_TEMPLATE.format(off=idx))
exec(GET_TEMPLATE.format(off=post))

View File

@@ -0,0 +1,12 @@
13106 13620 14134
bytearray(b'23')
bytearray(b'45')
bytearray(b'67')
17475 17989 18503
bytearray(b'CD')
bytearray(b'EF')
bytearray(b'GH')
20045 20559 21073
bytearray(b'MN')
bytearray(b'OP')
bytearray(b'QR')

View File

@@ -0,0 +1,41 @@
# Test boundary conditions for various architectures
SET_TEMPLATE = """
@micropython.viper
def set{off}(dest: ptr16):
dest[{off}] = {val}
set{off}(b)
print(b[{off} * 2:({off} + 1) * 2])
"""
TEST_DATA = (
(15, (0x4241, 0x4443, 0x4645)),
(127, (0x4847, 0x4A49, 0x4C4B)),
(2047, (0x4E4D, 0x504F, 0x5251)),
)
@micropython.viper
def set_index(dest: ptr16, i: int, val: int):
dest[i] = val
@micropython.viper
def set_index(dest: ptr16, i: int, val: int):
dest[i] = val
b = bytearray(5000)
for start, vals in TEST_DATA:
for i, v in enumerate(vals):
set_index(b, start + i, v)
print(b[(start + i) * 2 : (start + i + 1) * 2])
for i in range(len(b)):
b[i] = 0
for start, vals in TEST_DATA:
for i, v in enumerate(vals):
exec(SET_TEMPLATE.format(off=start + i, val=v + 0x0101))

View File

@@ -0,0 +1,18 @@
bytearray(b'AB')
bytearray(b'CD')
bytearray(b'EF')
bytearray(b'GH')
bytearray(b'IJ')
bytearray(b'KL')
bytearray(b'MN')
bytearray(b'OP')
bytearray(b'QR')
bytearray(b'BC')
bytearray(b'DE')
bytearray(b'FG')
bytearray(b'HI')
bytearray(b'JK')
bytearray(b'LM')
bytearray(b'NO')
bytearray(b'PQ')
bytearray(b'RS')

View File

@@ -0,0 +1,25 @@
# Test boundary conditions for various architectures
GET_TEMPLATE = """
@micropython.viper
def get{off}(src: ptr32) -> int:
return src[{off}]
print(b[{off} * 4:({off} + 1) * 4])
"""
@micropython.viper
def get_index(src: ptr32, i: int) -> int:
return src[i]
b = bytearray(5000)
b[24:43] = b"0123456789ABCDEFGHIJ"
b[248:268] = b"KLMNOPQRSTUVWXYZabcd"
b[4088:4108] = b"efghijklmnopqrstuvwx"
for pre, idx, post in (7, 8, 9), (63, 64, 65), (1023, 1024, 1025):
print(get_index(b, pre), get_index(b, idx), get_index(b, post))
exec(GET_TEMPLATE.format(off=pre))
exec(GET_TEMPLATE.format(off=idx))
exec(GET_TEMPLATE.format(off=post))

View File

@@ -0,0 +1,12 @@
926299444 1111570744 1178944579
bytearray(b'4567')
bytearray(b'89AB')
bytearray(b'CDEF')
1381060687 1448432723 1515804759
bytearray(b'OPQR')
bytearray(b'STUV')
bytearray(b'WXYZ')
1818978921 1886350957 1953722993
bytearray(b'ijkl')
bytearray(b'mnop')
bytearray(b'qrst')

View File

@@ -0,0 +1,35 @@
# Test boundary conditions for various architectures
TEST_DATA = (
(3, (0x04030201, 0x08070605, 0x0C0B0A09)),
(63, (0x100F0E0D, 0x14131211, 0x18171615)),
(1023, (0x1C1B1A19, 0x201F1E1D, 0x24232221)),
)
SET_TEMPLATE = """
@micropython.viper
def set{off}(dest: ptr32):
dest[{off}] = {val} & 0x3FFFFFFF
set{off}(b)
print(b[{off} * 4:({off} + 1) * 4])
"""
@micropython.viper
def set_index(dest: ptr32, i: int, val: int):
dest[i] = val
b = bytearray(5000)
for start, vals in TEST_DATA:
for i, v in enumerate(vals):
set_index(b, start + i, v)
print(b[(start + i) * 4 : (start + i + 1) * 4])
for i in range(len(b)):
b[i] = 0
for start, vals in TEST_DATA:
for i, v in enumerate(vals):
exec(SET_TEMPLATE.format(off=start + i, val=v + 0x01010101))

View File

@@ -0,0 +1,18 @@
bytearray(b'\x01\x02\x03\x04')
bytearray(b'\x05\x06\x07\x08')
bytearray(b'\t\n\x0b\x0c')
bytearray(b'\r\x0e\x0f\x10')
bytearray(b'\x11\x12\x13\x14')
bytearray(b'\x15\x16\x17\x18')
bytearray(b'\x19\x1a\x1b\x1c')
bytearray(b'\x1d\x1e\x1f ')
bytearray(b'!"#$')
bytearray(b'\x02\x03\x04\x05')
bytearray(b'\x06\x07\x08\t')
bytearray(b'\n\x0b\x0c\r')
bytearray(b'\x0e\x0f\x10\x11')
bytearray(b'\x12\x13\x14\x15')
bytearray(b'\x16\x17\x18\x19')
bytearray(b'\x1a\x1b\x1c\x1d')
bytearray(b'\x1e\x1f !')
bytearray(b'"#$%')

View File

@@ -0,0 +1,25 @@
# Test boundary conditions for various architectures
GET_TEMPLATE = """
@micropython.viper
def get{off}(src: ptr8) -> int:
return src[{off}]
print(get{off}(b))
"""
@micropython.viper
def get_index(src: ptr8, i: int) -> int:
return src[i]
b = bytearray(5000)
b[30:32] = b"123"
b[254:256] = b"456"
b[4094:4096] = b"789"
for pre, idx, post in (30, 31, 32), (254, 255, 256), (4094, 4095, 4096):
print(get_index(b, pre), get_index(b, idx), get_index(b, post))
exec(GET_TEMPLATE.format(off=pre))
exec(GET_TEMPLATE.format(off=idx))
exec(GET_TEMPLATE.format(off=post))

View File

@@ -0,0 +1,12 @@
49 50 51
49
50
51
52 53 54
52
53
54
55 56 57
55
56
57

View File

@@ -0,0 +1,30 @@
# Test boundary conditions for various architectures
TEST_DATA = ((49, 30, 3), (52, 254, 3), (55, 4094, 3))
SET_TEMPLATE = """
@micropython.viper
def set{off}(dest: ptr8):
dest[{off}] = {val}
set{off}(b)
print(b[{off}])
"""
@micropython.viper
def set_index(dest: ptr8, i: int, val: int):
dest[i] = val
b = bytearray(5000)
for val, start, count in TEST_DATA:
for i in range(count):
set_index(b, start + i, val + i)
print(b[start : start + count])
for i in range(len(b)):
b[i] = 0
for val, start, count in TEST_DATA:
for i in range(count):
exec(SET_TEMPLATE.format(off=start + i, val=val + i + 16))

View File

@@ -0,0 +1,12 @@
bytearray(b'123')
bytearray(b'456')
bytearray(b'789')
65
66
67
68
69
70
71
72
73