Request for new pseudoinstruction: dec X / dec Y #1042
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#1042
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I have a recommendation for a new pseudoinstruction, and explanation on why it's so useful.
Is this the right depot to file the issue in?
If yes, then I will change the title of the issue to:
Request for new pseudoinstruction:
dec X/dec YAssembler Syntax
dec <target>, where<target>is eitherXorYFor target
X:0b_000_ddddd_010_aaaaadddddrepresents the delay/side-set bitsaaaaarepresents the encoded address to jump toEdge cases
Normally, the
dec <target>pseudoinstruction encodes to ajmpto the next instruction in the program.Therefore,
pioasmwould need to handle the following two edges cases:.wrapdirective -- encode thejmpaddress to the.wraptargetjmpaddress to the.wraptargetWhy do this?
Two reasons: First, to increase awareness of how to do this. Secondly, to avoid incorrectly written implementations.
When looking for how to modify the data in a register, a user will first look at the
setandmovinstructions. The impression given is that only negation and reversing the bits are available. However, decrement is a supported atomic operation!There's also the problem of buggy attempts, where a person initially has an unconditional
jmp, needs to decrement the register at the same time, and converts that to ajmp (x--) label... thus introducing a bug, because if the register value pre-execution was zero, the jump will not happen. (yes, real world story)This would have saved me some time today, trying to come up with a dec X/Y solution. Would be really handy to not be bothered with a unique label that can potentially be wrong.
I've also been thinking recently about a new pseudo instruction like this.
It could be handy, it makes the code more readable and less error prone.
This fully backward-compatible change (only changes sources, no new emitted instructions) is still a feature worth adding....
I think it isn't as simple as it might look like. I think, currently, instructions and symbols use the same namespace. Any program that is using a symbol (or label)
decand was correct before would produce an error, unless the new instruction would, for example, only be enabled with a new directive or command line option.So it would require careful changes in the grammar otherwise (see e. g. also #1951 and #2163/#2484). But that would be nice as well…
I admit I'm having trouble visualizing a well-formed program that, with adding the
dec {x | y}pseudo-instruction, would fail to compile. For example, I think a label requires:? You seem more experienced with grammar parsing ...Could you provide simple example(s) that would cause trouble? (They'd also be useful for tests, since they'd be important edge cases.)
Let's say you had the following code already:
This currently works fine because
decisn't an instruction yet. To emulate that, replace bothdecwith a word that is already a keyword (let's say,nextorjmporXormanual), and you'll get an error.The current compiler might choose to emit an error for current keywords, when they are used as a label. I not yet seeing where this would be required behavior when parsing the .pio program?
At first glance, that appears to be a design choice, and not a hard requirement.
Here's what each line must parse as:
github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/parser.yy (L176-L185)Of interest are lines 179-181, which allow a
label_decl, alabel_declfollowed by aninstruction, or just aninstruction. Thelabel_declis defined to be anysymbol_def, followed byCOLON.github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/parser.yy (L191-L192)Meanwhile, each potential
instructionstarts with abase_instruction:github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/parser.yy (L251-L256)And ... none of the valid
base_instructionoverlap withsymbol_defbecausesymbol_defrequires a trailing colon:github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/parser.yy (L259-L275)And ... once a line is matching
jmp, theexpressionwould matchID(a deferred reference to a label).Thus, the context of the current parsing makes it clear whether
decis a label or instruction. Put another way, it appears that, if the line starts withdec, whether thatdecis a label or an instruction depends on whether it is followed byCOLON(aka:).Example using `dec` as both label and instruction
If I manually parse that, it seems to parse without error?
Am I missing a case where there would be ambiguity, or mandatory failure?
Even where there is a namespace collision, this is not a compatibility problem or caused by a new instruction. The parser functions
add_symbol()andadd_label()appear to have the potential to conflict:github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/parser.yy (L194-L195)But, the conflict is between the define and the label ... not the instruction?
Compare
add_instruction()vs.add_symbol()/add_label()github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/pio_assembler.cpp (L38-L53)github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/pio_types.h (L349-L352)github.com/raspberrypi/pico-sdk@ee68c78d0a/tools/pioasm/pio_assembler.cpp (L81-L97)My point is that it would be easier to do after some internal cleanup (separation of symbols, instructions, operands, directives; proper expressions; conditional assembly; etc.). Requests for
pioasmhave been queueing up for years (I guess it works passable enough and they don't have enough engineering time to justify them yet).note also that other things like CircuitPython support parsing the
.pioformatI suspect it wouldn't be a problem on CircuitPython's pioasm, though (I think, e. g.
nextis allowed as a label there while on SDK 2'spioasmit isn't anymore even with.pio_version 0).Still hopeful that useful pseudo-instructions such as
deccan be added.