Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit02e94ba

Browse files
Merge pull request#52 from wnienhaus/fixes-for-v1
More fixes towards v1.0
2 parentse647bcc +78e9812 commit02e94ba

File tree

6 files changed

+77
-28
lines changed

6 files changed

+77
-28
lines changed

‎esp32_ulp/assemble.py‎

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
ESP32 ULP Co-Processor Assembler
33
"""
44

5+
importre
56
from .importopcodes
67
from .nocommentimportremove_commentsasdo_remove_comments
78
from .utilimportgarbage_collect
@@ -91,6 +92,12 @@ def __init__(self, symbols=None, bases=None, globals=None):
9192
self.symbols=SymbolTable(symbolsor {},basesor {},globalsor {})
9293
opcodes.symbols=self.symbols# XXX dirty hack
9394

95+
# regex for parsing assembly lines
96+
# format: [[whitespace]label:][whitespace][opcode[whitespace arg[,arg...]]]
97+
# where [] means optional
98+
# initialised here once, instead of compiling once per line
99+
self.line_regex=re.compile(r'^(\s*([a-zA-Z0-9_$.]+):)?\s*((\S*)\s*(.*))$')
100+
94101
definit(self,a_pass):
95102
self.a_pass=a_pass
96103
self.sections=dict(text=[],data=[])
@@ -108,25 +115,14 @@ def parse_line(self, line):
108115
"""
109116
ifnotline:
110117
return
111-
has_label=line[0]notin'\t .'
112-
ifhas_label:
113-
label_line=line.split(None,1)
114-
iflen(label_line)==2:
115-
label,line=label_line
116-
else:# 1
117-
label,line=label_line[0],None
118-
label=label.rstrip(':')
119-
else:
120-
label,line=None,line.lstrip()
121-
iflineisNone:
122-
opcode,args=None, ()
123-
else:
124-
opcode_args=line.split(None,1)
125-
iflen(opcode_args)==2:
126-
opcode,args=opcode_args
127-
args=tuple(arg.strip()forarginargs.split(','))
128-
else:# 1
129-
opcode,args=opcode_args[0], ()
118+
119+
matches=self.line_regex.match(line)
120+
label,opcode,args=matches.group(2),matches.group(4),matches.group(5)
121+
122+
label=labeliflabelelseNone# force empty strings to None
123+
opcode=opcodeifopcodeelseNone# force empty strings to None
124+
args=tuple(arg.strip()forarginargs.split(','))ifargselse ()
125+
130126
returnlabel,opcode,args
131127

132128
defsplit_statements(self,lines):

‎esp32_ulp/opcodes.py‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,9 @@ def get_rel(arg):
342342
ifarg.type==IMM:
343343
ifarg.value&3!=0:# bitwise version of: arg.value % 4 != 0
344344
raiseValueError('Relative offset must be a multiple of 4')
345-
returnarg.value>>2# bitwise version of: arg.value // 4
345+
returnIMM,arg.value>>2# bitwise version of: arg.value // 4
346346
ifarg.type==SYM:
347-
returnsymbols.resolve_relative(arg.value)
347+
returnSYM,symbols.resolve_relative(arg.value)
348348
raiseTypeError('wanted: immediate, got: %s'%arg.raw)
349349

350350

@@ -449,7 +449,7 @@ def i_tsens(reg_dest, delay):
449449
return_tsens.all
450450

451451

452-
defi_adc(reg_dest,adc_idx,mux):
452+
defi_adc(reg_dest,adc_idx,mux,_not_used=None):
453453
_adc.dreg=get_reg(reg_dest)
454454
_adc.mux=get_imm(mux)
455455
_adc.sar_sel=get_imm(adc_idx)
@@ -619,7 +619,8 @@ def i_jump(target, condition='--'):
619619
raiseValueError("invalid flags condition")
620620
iftarget.type==IMMortarget.type==SYM:
621621
_bx.dreg=0
622-
_bx.addr=get_abs(target)
622+
# we track label addresses in 32bit words, but immediate values are in bytes and need to get divided by 4.
623+
_bx.addr=get_abs(target)iftarget.type==SYMelseget_abs(target)>>2# bitwise version of "// 4"
623624
_bx.unused=0
624625
_bx.reg=0
625626
_bx.type=jump_type
@@ -652,7 +653,7 @@ def _jump_relr(threshold, cond, offset):
652653

653654

654655
defi_jumpr(offset,threshold,condition):
655-
offset=get_rel(offset)
656+
offset_type,offset=get_rel(offset)
656657
threshold=get_imm(threshold)
657658
condition=get_cond(condition)
658659
ifcondition=='lt':
@@ -669,7 +670,11 @@ def i_jumpr(offset, threshold, condition):
669670
# jump over next JUMPR
670671
skip_ins=_jump_relr(threshold+1,BRCOND_GE,2)
671672
# jump to target
672-
offset-=1# adjust for the additional JUMPR instruction
673+
if (offset_type==IMMandoffset<0)oroffset_type==SYM:
674+
# adjust for the additional JUMPR instruction
675+
# for IMM offsets, the offset is relative to the 2nd instruction, so only backwards jumps need adjusting
676+
# for SYM offsets, label offsets already include the extra instruction, so both directions need adjusting
677+
offset-=1
673678
jump_ins=_jump_relr(threshold,BRCOND_GE,offset)
674679
return (skip_ins,jump_ins)
675680
else:
@@ -691,7 +696,7 @@ def _jump_rels(threshold, cond, offset):
691696

692697

693698
defi_jumps(offset,threshold,condition):
694-
offset=get_rel(offset)
699+
offset_type,offset=get_rel(offset)
695700
threshold=get_imm(threshold)
696701
condition=get_cond(condition)
697702
ifcondition=='lt':
@@ -711,7 +716,11 @@ def i_jumps(offset, threshold, condition):
711716
# jump over next JUMPS
712717
skip_ins=_jump_rels(threshold,skip_cond,2)
713718
# jump to target
714-
offset-=1# adjust for the additional JUMPS instruction
719+
if (offset_type==IMMandoffset<0)oroffset_type==SYM:
720+
# adjust for the additional JUMPS instruction
721+
# for IMM offsets, the offset is relative to the 2nd instruction, so only backwards jumps need adjusting
722+
# for SYM offsets, label offsets already include the extra instruction, so both directions need adjusting
723+
offset-=1
715724
jump_ins=_jump_rels(threshold,jump_cond,offset)
716725

717726
return (skip_ins,jump_ins)

‎tests/02_compat_rtc_tests.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ for src_file in ulptool/src/ulp_examples/*/*.s binutils-esp32ulp/gas/testsuite/g
6666
test_name="${src_name##*/}"
6767

6868
# for now, skip files that contain known bugs in esp32_ulp (essentially a todo list of what to fix)
69-
forIinesp32ulp_all esp32ulp_globalsesp32ulp_jumpr esp32ulp_ranges test_reg;do
69+
forIin esp32ulp_jumpr esp32ulp_ranges;do
7070
if ["${test_name}"="$I" ];then
7171
# these are old bugs, and not related to the RTC macro handling functionality
7272
# they will still be great to fix over time

‎tests/assemble.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,32 @@ def test_parse_line():
5353
asserta.parse_line(next(lines))== (None,'.data', ())# test left-aligned directive is not treated as label
5454

5555

56+
deftest_parse_labels_correctly():
57+
"""
58+
description of what defines a label
59+
https://sourceware.org/binutils/docs/as/Statements.html
60+
https://sourceware.org/binutils/docs/as/Labels.html
61+
"""
62+
a=Assembler()
63+
asserta.parse_line('')isNone
64+
asserta.parse_line('label: .set const, 42')== ('label','.set', ('const','42',))
65+
asserta.parse_line('label:.set const, 42')== ('label','.set', ('const','42',))
66+
asserta.parse_line('label:')== ('label',None, ())
67+
asserta.parse_line(' label:')== ('label',None, ())
68+
asserta.parse_line(' label: ')== ('label',None, ())
69+
asserta.parse_line('nop ')== (None,'nop', ())
70+
asserta.parse_line('.set c, 1 ')== (None,'.set', ('c','1',))
71+
asserta.parse_line('invalid : nop')== (None,'invalid', (': nop',))# no whitespace between label and colon
72+
asserta.parse_line('.string "hello world"')== (None,'.string', ('"hello world"',))
73+
asserta.parse_line('.string "hello : world"')== (None,'.string', ('"hello : world"',))# colon in string
74+
asserta.parse_line('label::')== ('label',':', ())
75+
asserta.parse_line('label: :')== ('label',':', ())
76+
asserta.parse_line('a_label:')== ('a_label',None, ())
77+
asserta.parse_line('$label:')== ('$label',None, ())
78+
asserta.parse_line('.label:')== ('.label',None, ())
79+
asserta.parse_line('&label:')== (None,'&label:', ())# & not a valid char in a label
80+
81+
5682
deftest_parse():
5783
a=Assembler()
5884
lines=remove_comments(src)
@@ -260,6 +286,7 @@ def test_support_multiple_statements_per_line():
260286

261287

262288
test_parse_line()
289+
test_parse_labels_correctly()
263290
test_parse()
264291
test_assemble()
265292
test_assemble_bss()

‎tests/compat/fixes.S‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ entry:
2828
# interpret ; as statement separator - this results in 2 NOP machine instructions
2929
nop;nop;
3030

31+
# adc supports an undocumented 4th argument, which should be entirely ignored
32+
# binutils-esp32ulp also ignores this argument, if present, see:
33+
# https://github.com/espressif/binutils-esp32ulp/blob/249ec34cc2c9574a86f3f86bbb175a863f988bcf/gas/config/esp32ulp-parse.y#L810
34+
adc r1,0,1,100
35+
3136
halt

‎tests/compat/jumps.S‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
entry:
66
nop
77

8+
# simple jumps
9+
jump entry
10+
jump later
11+
jump0x120, EQ
12+
jump-288, EQ
13+
814
# jumps with labels
915
jumps entry,42, lt
1016
jumps entry,42, lt
@@ -20,12 +26,15 @@ entry:
2026

2127
# jumps with immediate offset (specifiedin bytes, but real instruction uses words)
2228
jumps0,42, lt
29+
jumps0,42, eq # dual-instruction condition
2330

2431
jumps4,42, lt
32+
jumps4,42, eq # dual-instruction condition
2533
jumps8,42, lt
2634
jumps32,42, lt
2735

2836
jumps-4,42, lt
37+
jumps-4,42, eq # dual-instruction condition
2938
jumps-8,42, lt
3039
jumps-32,42, lt
3140

@@ -46,12 +55,15 @@ entry:
4655

4756
# jumpr with immediate offset (specifiedin bytes, but real instruction uses words)
4857
jumpr0,42, lt
58+
jumpr0,42, eq # dual-instruction condition
4959

5060
jumpr4,42, lt
61+
jumpr4,42, eq # dual-instruction condition
5162
jumpr8,42, lt
5263
jumpr32,42, lt
5364

5465
jumpr-4,42, lt
66+
jumpr-4,42, eq # dual-instruction condition
5567
jumpr-8,42, lt
5668
jumpr-32,42, lt
5769

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp