Skip to content

Commit 7eda90c

Browse files
committed
fix relative jumps for immediate offsets
The JUMPR and JUMPS instructions in assembly are defined to take an offset in bytes, but the real CPU instruction expects this to be expressed in 32-bit words. Thus, the assembler needs to translate offsets into words (32-bits). i.e. 4 bytes is 1 word. Only immediate values, which are multiples of 4 are allowed. Other values will result in a ValueError. (binutils-esp32ulp actually allows other values and rounds the result, but to get the exact same behaviour as binutils with its peculiarities would require a bigger change for a case, which might more likely represent a mistake than a useful offset) Note, since py-esp32-ulp already tracks label offsets in 32-bit words internally, this conversion is only necessary for immediate offsets.
1 parent 82e2765 commit 7eda90c

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

Diff for: esp32_ulp/opcodes.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,9 @@ def get_rel(arg):
340340
if isinstance(arg, str):
341341
arg = arg_qualify(arg)
342342
if arg.type == IMM:
343-
return arg.value
343+
if arg.value & 3 != 0: # bitwise version of: arg.value % 4 != 0
344+
raise ValueError('Relative offset must be a multiple of 4')
345+
return arg.value >> 2 # bitwise version of: arg.value // 4
344346
if arg.type == SYM:
345347
return symbols.resolve_relative(arg.value)
346348
raise TypeError('wanted: immediate, got: %s' % arg.raw)

Diff for: tests/compat/jumps.S

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
entry:
44
nop
55

6+
# jumps with labels
67
jumps entry, 42, lt
78
jumps entry, 42, lt
89
jumps later, 42, lt
@@ -15,6 +16,18 @@ entry:
1516
jumps entry, 42, gt
1617
jumps later, 42, gt
1718

19+
# jumps with immediate offset (specified in bytes, but real instruction uses words)
20+
jumps 0, 42, lt
21+
22+
jumps 4, 42, lt
23+
jumps 8, 42, lt
24+
jumps 32, 42, lt
25+
26+
jumps -4, 42, lt
27+
jumps -8, 42, lt
28+
jumps -32, 42, lt
29+
30+
# jumpr with labels
1831
jumpr entry, 42, lt
1932
jumpr later, 42, lt
2033
jumpr entry, 42, ge
@@ -26,6 +39,17 @@ entry:
2639
jumpr entry, 42, eq
2740
jumpr later, 42, eq
2841

42+
# jumpr with immediate offset (specified in bytes, but real instruction uses words)
43+
jumpr 0, 42, lt
44+
45+
jumpr 4, 42, lt
46+
jumpr 8, 42, lt
47+
jumpr 32, 42, lt
48+
49+
jumpr -4, 42, lt
50+
jumpr -8, 42, lt
51+
jumpr -32, 42, lt
52+
2953
nop
3054
nop
3155
nop

0 commit comments

Comments
 (0)