summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2025-08-17 07:28:35 +0200
committerDamien George <damien@micropython.org>2025-08-19 12:40:29 +1000
commitbd413d3d853e2c1fc0382b328176ff912d79da70 (patch)
tree330a870baedad7f8aebc138cddc0d97419ea9e50
parent22deeeb8db1305b292e9146b7b00a58207755693 (diff)
py/asmthumb: Fix T3 encoding of conditional branches.
This commit fixes the encoding of conditional branch opcodes emitted for ARMv7-M targets, when the emitter decides to use the T3 encoding for said operation. Fields J1 and J2 are now present in the generated opcode word, along with correcting some minor issues in bitmasks and shifts computation. This fixes #17940. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
-rw-r--r--py/asmthumb.c5
-rw-r--r--tests/micropython/viper_large_jump.py20
-rw-r--r--tests/micropython/viper_large_jump.py.exp1
3 files changed, 23 insertions, 3 deletions
diff --git a/py/asmthumb.c b/py/asmthumb.c
index 93860d2fd..58cc7aea8 100644
--- a/py/asmthumb.c
+++ b/py/asmthumb.c
@@ -267,9 +267,8 @@ bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) {
#define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff))
-// all these bit-arithmetic operations need coverage testing!
-#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f))
-#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff))
+#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 12) & 0x003f))
+#define OP_BCC_W_LO(byte_offset) (0x8000 | (((byte_offset) >> 5) & 0x2000) | (((byte_offset) >> 8) & 0x0800) | (((byte_offset) >> 1) & 0x07ff))
bool asm_thumb_bcc_nw_label(asm_thumb_t *as, int cond, uint label, bool wide) {
mp_uint_t dest = get_label_dest(as, label);
diff --git a/tests/micropython/viper_large_jump.py b/tests/micropython/viper_large_jump.py
new file mode 100644
index 000000000..1c5913dec
--- /dev/null
+++ b/tests/micropython/viper_large_jump.py
@@ -0,0 +1,20 @@
+COUNT = 600
+
+
+try:
+ code = """
+@micropython.viper
+def f() -> int:
+ x = 0
+ while x < 10:
+"""
+ for i in range(COUNT):
+ code += " x += 1\n"
+ code += " return x"
+ exec(code)
+except MemoryError:
+ print("SKIP-TOO-LARGE")
+ raise SystemExit
+
+
+print(f())
diff --git a/tests/micropython/viper_large_jump.py.exp b/tests/micropython/viper_large_jump.py.exp
new file mode 100644
index 000000000..e9f960cf4
--- /dev/null
+++ b/tests/micropython/viper_large_jump.py.exp
@@ -0,0 +1 @@
+600