GETNIBx,SETNIBx bug
ozpropdev
Posts: 2,792
Hi Chip
I've discovered a little bug in the GETNIBx instruction.
I've discovered a little bug in the GETNIBx instruction.
GETNIB3..GETNIB0 work Ok GETNIB7..GETNIB4 return incorrect values.Brian
Comments
If I understand ROLNIBx correctly a nibble is shifted in in at nibble x
Is that correct?
(...and how are you inspecting values of registers, by the way? Curious wanna-be testers would like to know! I'm still just marveling at the blinking lights!)
Code is part of a large program. I will have to edit it severely to post a usable piece.
If time permits I will do that.
Hopefully, I can try some things this afternoon!
Not sure on the rolnibx one though? I would have expected it to work differently than ozpropdev is expecting. In my expectation, $12345678 would become $12345671 for rolnib0 regx, #$1. The top bit of the first nibble would rotate left one step around to the bottom bit of the first nibble. If it is really meant to "insert" the immediate value into the given nibble via rotating in 4 bits, then that seems even more oddball to me...
Maybe the name rolnibx is just poorly chosen, and it means something else?
Grabbing IP, or really doing that feature right would take considerable test time.
Done this way, we can arrive at a software solution and improve it over time.
My .02 on it
It could be changed to setnib n, reg, [#|reg] and getnib n, reg, [#|reg]
I think a pass needs to be made over the instruction set to clean up the syntax/naming a bit. It's ok to have 3 operands in cases where it makes sense, instead of doing what Chip did with the 8 variants of the same instruction.
From Chips comments on streaming, 4b wide is on his list, and that, with simple QuadSPI HW would allow full bandwidth burst streaming over QuadSPI.
Parts out there can go to > 100MHz
Only Chip knows what is 'correct' but that's not quite what I'd expect.
I'd call the above example more an Insert Nibble operation.
Nibbles to right of index stay, and nibble inserts and pushes higher ones left.
I'd expect ROLNIB would work like rotate thru Carry, only with a 4 bit carry.
ie like this :
I like your interpretation better than mine.
A shift nibble in from right. Very useful.
Now we wait to see what Chip intended
Left open is the question of what happens to the Cy4 ?
When you use RLC opcodes, the carry has both a write then a read bit value.
ie is ROLNIBn intended as a 'Write only' opcode ?
ROLNIBx D, S/#
It rotates the Xth nib from S/# into D!
The ROLNIB5-7 is still broken. This is likely a real bug, since it's a different opcode. But the ROLNIB0-3 is working just fine (now that I see what it's doing)!
ROLBYTx and ROLWRDx work correctly.
I will have these fixed in the new REP release.
ROLNIB takes nibble 0..7 from S and puts it into the lower nibble of D, while shifting D up by one nibible. It's a way to rotate a whole nibble into D.
I suppose this allows the QSPI-type inputs to be more flexible; just nibble-align them on INx, then you can "ROLNIBx buffer, INA" each cycle into a 32-bit buffer.
I can also see how this would be useful for changing endianness (can't remember if there's a dedicated instruction anymore):
Chip, make sure you look at GETNIB5-7 as well. Same issue. I haven't tested SETNIBx, but @ozpropdev mentions it in the title...
The P2-Hot ESWAP8 is gone but MOVBYTS can do the same job.
This is what is was:
And this is what it needed to become:
This used to be okay, but when I discovered the ==? operator that allows "?" wildcards, I got rid of the discrete masks I had in each of these `op1 declarations and forgot to put an extra "?" in the SETNIB/GETNIB/ROLNIB instructions.
This bug is out of the way. Thanks for finding it!
I know it looks silly, but the deal is that these 0..7's are constants and variables cannot be used for them. So, it seemed kind of like a teaser to have a 3rd operand. I actually used to have it this way in the assembler. I can put it back. In fact, if I do put it back, it will at least allow for some compile-time variance. That's worthwhile.
I prefer the 3 operand form even if one is always a constant. It can be useful at compile time, and for using named CONs instead of numbers to impart proper meaning in context.