Skip to content

Commit fb4fade

Browse files
committed
pioasm: add target for .wrap, dot symbol, .word as instruction (#2163)
1 parent c9c3825 commit fb4fade

File tree

5 files changed

+33
-5
lines changed

5 files changed

+33
-5
lines changed

tools/pioasm/lexer.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ output_fmt [^%\n]+
220220
221221
{comment} { }
222222
223+
"." return yy::parser::make_DOT(loc);
224+
223225
. { throw yy::parser::syntax_error(loc, "invalid character: " + std::string(yytext)); }
224226
225227
%%

tools/pioasm/parser.yy

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
DOT_SET ".set"
8686
DOT_OUT ".out"
8787
DOT_IN ".in"
88+
DOT "."
8889

8990
JMP "jmp"
9091
WAIT "wait"
@@ -203,8 +204,8 @@ directive:
203204
| DOT_OUT value direction autop threshold { pioasm.get_current_program(@1, ".out", true).set_out(@$, $2, $3, $4, $5); }
204205
| DOT_SET value { pioasm.get_current_program(@1, ".set", true).set_set_count(@$, $2); }
205206
| WRAP_TARGET { pioasm.get_current_program(@1, ".wrap_target").set_wrap_target(@$); }
207+
| WRAP expression { pioasm.get_current_program(@1, ".wrap").set_wrap(@$, $2); }
206208
| WRAP { pioasm.get_current_program(@1, ".wrap").set_wrap(@$); }
207-
| WORD value { pioasm.get_current_program(@1, "instruction").add_instruction(std::shared_ptr<instruction>(new instr_word(@$, $2))); }
208209
| LANG_OPT NON_WS NON_WS ASSIGN INT { pioasm.get_current_program(@1, ".lang_opt").add_lang_opt($2, $3, std::to_string($5)); }
209210
| LANG_OPT NON_WS NON_WS ASSIGN STRING { pioasm.get_current_program(@1, ".lang_opt").add_lang_opt($2, $3, $5); }
210211
| LANG_OPT NON_WS NON_WS ASSIGN NON_WS { pioasm.get_current_program(@1, ".lang_opt").add_lang_opt($2, $3, $5); }
@@ -224,6 +225,7 @@ directive:
224225
/* value is a more limited top level expression... requiring parenthesis */
225226
%type <std::shared_ptr<resolvable>> value;
226227
value: INT { $$ = resolvable_int(@$, $1); }
228+
| DOT { $$ = resolvable_int(@$, pioasm.get_current_program(@1, ".").instructions.size()); }
227229
| ID { $$ = std::shared_ptr<resolvable>(new name_ref(@$, $1)); }
228230
| LPAREN expression RPAREN { $$ = $2; }
229231

@@ -257,7 +259,8 @@ instruction:
257259

258260
%type <std::shared_ptr<instruction>> base_instruction;
259261
base_instruction:
260-
NOP { $$ = std::shared_ptr<instruction>(new instr_nop(@$)); }
262+
WORD value { $$ = std::shared_ptr<instruction>(new instr_word(@$, $2)); }
263+
| NOP { $$ = std::shared_ptr<instruction>(new instr_nop(@$)); }
261264
| JMP condition comma expression { $$ = std::shared_ptr<instruction>(new instr_jmp(@$, $2, $4)); }
262265
| WAIT value wait_source { $$ = std::shared_ptr<instruction>(new instr_wait(@$, $2, $3)); }
263266
| WAIT wait_source { $$ = std::shared_ptr<instruction>(new instr_wait(@$, resolvable_int(@$, 1), $2)); }

tools/pioasm/pio_assembler.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ void program::set_wrap(const yy::location &l) {
161161
wrap = resolvable_int(l, instructions.size() - 1);
162162
}
163163

164+
void program::set_wrap(const yy::location &l, rvalue target) {
165+
set_wrap(l);
166+
167+
if (wrap_target) {
168+
std::stringstream msg;
169+
msg << ".wrap_target was already specified at " << wrap_target->location;
170+
throw syntax_error(l, msg.str());
171+
}
172+
wrap_target = std::move(target);
173+
}
174+
164175
void program::set_wrap_target(const yy::location &l) {
165176
if (wrap_target) {
166177
std::stringstream msg;
@@ -299,12 +310,12 @@ raw_encoding instruction::raw_encode(program& program) {
299310
throw syntax_error(location, "internal error");
300311
}
301312

302-
uint instr_word::encode(program &program) {
313+
raw_encoding instr_word::raw_encode(program& program) {
303314
uint value = encoding->resolve(program);
304315
if (value > 0xffffu) {
305316
throw syntax_error(location, ".word value must be a positive 16 bit value");
306317
}
307-
return value;
318+
return {inst_type(0), value >> 5, value & 0x1fu};
308319
}
309320

310321
uint instr_mov::get_push_get_index(const program &program, extended_mov index) {

tools/pioasm/pio_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ struct program : public src_item {
321321

322322
void set_wrap(const yy::location &l);
323323

324+
void set_wrap(const yy::location &l, rvalue target);
325+
324326
void set_sideset(const yy::location &l, rvalue _sideset, bool optional, bool pindirs) {
325327
sideset = rvalue_loc(_sideset, l);
326328
sideset_opt = optional;
@@ -486,7 +488,7 @@ struct instr_word : public instruction {
486488

487489
instr_word(const yy::location &l, rvalue encoding) : instruction(l), encoding(std::move(encoding)) {}
488490

489-
uint encode(program &program) override;
491+
raw_encoding raw_encode(program &program) override;
490492
};
491493

492494
#endif

tools/pioasm/test/amethyst.pio

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ wait gpio 40
4545
.mov_status txfifo < 12
4646
.mov_status irq next set 3
4747

48+
.program wrap
49+
decrement:
50+
jmp x--, .+1
51+
skip:
52+
.wrap .+1
53+
delay:
54+
jmp x--, .
55+
jump:
56+
.word (.-1) [2]
57+
4858
.program python
4959
.pio_version 1
5060
wait 0 jmppin

0 commit comments

Comments
 (0)