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:
(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.)
If 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.
Here, 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:
This 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.