Fix LD/ST instruction encoding #25
Description
Currently, LD/ST instructions are horribly broken. The problem lies with an inconsistency in the AVR ISR.
From the official AVR instruction set manual:
LD Rd, X
=> 1001 000d dddd 1100
LD Rd, X+
=> 1001 000d dddd 1101
LD Rd, -X
=> 1001 000d dddd 1110
LD Rd, Y
=> 1000 000d dddd 1000
LD Rd, Y+
=> 1001 000d dddd 1001
LD Rd, -Y
=> 1001 000d dddd 1010
LD Rd, Z
=> 1000 000d dddd 0000
LD Rd, Z+
=> 1001 000d dddd 0001
LD Rd, -Z
=> 1001 000d dddd 0010
Several pattens form to give this prototype:
<100 |000d|dddd|ppmm|>
Where
ddddd
is the destination 8 bit general purpose register numberpp
is the pointer register11
for X10
for Y00
for Z
mm
is the mode00
for normal01
for post-increment10
for pre-decrement
Note the empty space in the forth digit - this is where the inconsistency lies. It is sometimes 1
and sometimes 0
, and I cannot see a pattern.
Looking at the variants for the Y and Z registers, it could be that the digit is set to 1
if the mode is not normal, but then looking at
X, this proves to not be the case.
I could manually check each instruction case, and set the bit appropriately, although I do not know how (or if it is possible) to express this in LLVM tablegen.
It might be possible to do this in the C++ code itself, but I feel that this would be a very ugly hack.
There is possibly a pattern, but one which I cannot see. I cannot find any documentation on the internet about this.