pnut v34s assembler bug?
Seairth
Posts: 2,474
in Propeller 2
I took this code out of the docs and compiled it:
The output I am getting for these instructions are:
DAT
ORGH $01000
ORG 0 'cog code
cog JMP #cog '$FD9FFFFC cog to cog, relative
JMP #\cog '$FD800000 cog to cog, force absolute
JMP #@cog '$FD801000 cog to hub, always absolute
JMP #\@cog '$FD801000 cog to hub, always absolute
JMP #hub '$FD802000 cog to hub, always absolute
JMP #\hub '$FD802000 cog to hub, always absolute
JMP #@hub '$FD802000 cog to hub, always absolute
JMP #\@hub '$FD802000 cog to hub, always absolute
ORGH $02000 'hub code
hub JMP #cog '$FD800000 hub to cog, always absolute
JMP #\cog '$FD800000 hub to cog, always absolute
JMP #@cog '$FD9FEFF4 hub to hub, relative
JMP #\@cog '$FD801000 hub to hub, force absolute
JMP #hub '$FD9FFFEC hub to hub, relative
JMP #\hub '$FD802000 hub to hub, force absolute
JMP #@hub '$FD9FFFE4 hub to hub, relative
JMP #\@hub '$FD802000 hub to hub, force absolute
The output I am getting for these instructions are:
FD9FFFFC ' same FD800000 ' same FD801000 ' same FD801000 ' same FD803000 ' different. bad encoding? FD803000 ' different. bad encoding? FD802000 ' same FD802000 ' same FD800000 ' same FD800000 ' same FD9FEFF4 ' same FD801000 ' same FD900FCC ' different. bad encoding? FD802FE0 ' different. bad encoding? FD9FFFE4 ' same FD802000 ' same

Comments
Here's a small program that demonstrates the pattern:
DAT org not dirb ' F623F7FB setbyte outb, #$F, #3 ' F8DFFA0F lp not outb ' F623FBFD ' FF802625 waitx ##20_000_000/4 ' FD66801F jmp #lp ' FD9FFFF0(note: I realize others may already know this, but it's not documented in the the Google Doc, doesn't match the documentation in the spreadsheet, and seems to follow a different encoding rule than the other relative branch instructions. I'm trying to nail this all down so that I can get the docs updated appropriately.)
DAT org not dirb ' F623F7FB setbyte outb, #$F, #3 ' F8DFFA0F jmp #\@lp ' FD800400 orgh $400 lp not outb ' F623FBFD ' FF802625 waitx ##20_000_000/4 ' FD66801F jmp #@lp ' FD9FFFF0If I remove the "@" from the last line, the program breaks. This seems to match the encoding issue in the 13th JMP in the original post. More generally, it seems that the hub address is not being calculated correctly unless "@" is used.
DAT org not dirb ' F623F7FB jmp #\@hp ' FD800400 lp not outb ' F623FBFD ' FF802625 waitx ##20_000_000/4 ' FD66801F jmp #lp ' FD9FFFF0 orgh $400 hp setbyte outb, #$F, #3 ' F8DFFA0F jmp #\lp ' FD800002Here, you will notice that the absolute jump from cog to hub was the hub's byte address ($00400), whereas the jump from from hub to cog was the cog's address ($002). For cog address, absolute is the actual address, but relative (as seen above) must be (cog_address << 2).
(edit: corrected relative equations.)
EDIT: It's interesting that adding an @ makes it work ...
Yep, that's fixed the crashes with calling hubexec->hubexec ...
and now same for lutexec->hubexec ...
and also true for LOC instruction in same conditions.
Here's the non-broken one:
Good to know. It looks like is's more generally the handing of hub labels when @ isn't used.
EDIT: Attached an example testing of the bug. And my old loc-bug test code also trips up on it:
DAT org not dirb ' F623F7FB setbyte outb, #$F, #3 ' F8DFFA0F lp not outb ' F623FBFD ' FF802625 waitx ##20_000_000/4 ' FD66801F jmprel #lp ' FD640430This means #D was encoded as $002. But I think it should be encoded as FD67F830, making #D = $1FC (-4).
(note also that I happen to have an outstanding comment/question on the docs for JMPREL that's somewhat related.
This is correct behaviour.
Ok, so this prompted me to try some other variants. The result is:
- The register-mode value can be positive or negative.
- The immediate-mode value can only be positive. (this is not apparent from the spreadsheet docs.)
In which case, the use of a label in an immediate value seems risky and not what the user wants, most of the time. At the very least, the labels should be calculated using their relative address, so that my code above would throw the same error that's thrown if I try:At the same time, this would likely result in the correct forward-relative offset for the most common use case. Admittedly, this is just like JMP #A at that point, but less flexible.
So, I'm going to go out on a limb, and suggest that the documentation for JMPREL be changed to remove mention of the relative-mode addressing (and hardcode the L field to zero). This would make it clear that there is exactly one instruction used for relative immediate-mode jumps.
Not sure about removing mention of immediate addressing though. Maybe stating its limit and referring readers to JMP #A as a superior equivalent.