<div dir="ltr">I'm attempting to implement codegen support for the AVR <a href="http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_ST.html">ST/LD</a> family of instructions.<div><br></div><div>The binary encoding is not particularly consistent -- take a look at this table of variants of LD, along with their machine code representation:</div><div><br></div><div><span style="font-family:monospace,monospace"># load 8 bits from pointer register X into general purpose Rd</span><br></div><div><span style="font-family:monospace,monospace"><br></span></div><div><div><font face="monospace, monospace">ld Rd, X `1001 000d dddd 1100`</font></div><div><font face="monospace, monospace">ld Rd, X+ `1001 000d dddd 1101` (load with postincrement)</font></div><div><font face="monospace, monospace">ld Rd, -X `1001 000d dddd 1110` (load with predecrement)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">ld Rd, Y `1000 000d dddd 1000`</font></div><div><font face="monospace, monospace">ld Rd, Y+ `1001 000d dddd 1001`</font></div><div><font face="monospace, monospace">ld Rd, -Y `1001 000d dddd 1010`</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">ld Rd, Z `1000 000d dddd 0000`</font></div><div><font face="monospace, monospace">ld Rd, Z+ `1001 000d dddd 0001`</font></div><div><font face="monospace, monospace">ld Rd, -Z `1001 000d dddd 0010`</font></div></div><div><font face="monospace, monospace"> ^</font></div><div><font face="monospace, monospace"> |</font></div><div><font face="monospace, monospace"> Note this one inconsistent bit</font></div><div><br></div><div><font face="arial, helvetica, sans-serif">One way to solve this solution would be to to describe them in InstrInfo.td as seperate instructions. Note that R27R26 is a pointer register defined in AVRRegisterInfo.td, and 'X' is an alias for this.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><pre style="color:rgb(0,0,0)">let Uses<span class="" style="color:rgb(102,51,0);font-weight:bold"> = [</span>R27R26<span class="" style="color:rgb(102,51,0);font-weight:bold">],</span>
canFoldAsLoad<span class="" style="color:rgb(102,51,0);font-weight:bold"> =</span><span class="" style="color:rgb(153,153,0)"> 1</span><span class="" style="color:rgb(102,51,0);font-weight:bold">,</span>
isReMaterializable<span class="" style="color:rgb(102,51,0);font-weight:bold"> =</span><span class="" style="color:rgb(153,153,0)"> 1</span> in
def LDRdX<span class="" style="color:rgb(102,51,0);font-weight:bold"> :</span> FSTLDPtrReg<span class="" style="color:rgb(102,51,0);font-weight:bold"><</span>0b0<span class="" style="color:rgb(102,51,0);font-weight:bold">,
(</span>outs GPR8<span class="" style="color:rgb(102,51,0);font-weight:bold">:</span>$reg<span class="" style="color:rgb(102,51,0);font-weight:bold">),
(</span>ins<span class="" style="color:rgb(102,51,0);font-weight:bold">),</span><span class="" style="color:rgb(0,153,0)">
"ld\t$reg, X"</span><span class="" style="color:rgb(102,51,0);font-weight:bold">,
[(</span>set GPR8<span class="" style="color:rgb(102,51,0);font-weight:bold">:</span>$reg<span class="" style="color:rgb(102,51,0);font-weight:bold">, (</span>load R27R26<span class="" style="color:rgb(102,51,0);font-weight:bold">))]>;</span></pre></div><div><pre style="color:rgb(0,0,0)">def LDRdY<span class="" style="color:rgb(102,51,0);font-weight:bold"> :</span> FSTLDPtrReg<span class="" style="color:rgb(102,51,0);font-weight:bold"><</span>0b0<span class="" style="color:rgb(102,51,0);font-weight:bold">,</span></pre><pre style="color:rgb(0,0,0)"><span class="" style="color:rgb(102,51,0);font-weight:bold">// ...</span></pre></div><div><font face="arial, helvetica, sans-serif"> When I do this, however, I get errors that the pointer register is an invalid operand type.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Another solution might be to have a generic 'LD' pseudo instruction, which is later lowered into one of the 9 variants, which each have the correct encoding. This is a messy, hacky solution, which also bloats the code a fair bit more.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">One last solution is to 'make up a pattern' for the inconsistent bit that fits.</font></div><div><font face="arial, helvetica, sans-serif">It is:</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">I</font><span style="font-family:arial,helvetica,sans-serif">nconsistent bit = (postinc OR predec) OR IsPtrXReg</span></div><div><br></div><div>Where 'postinc' and 'predec' is 1 if the respective mode is used, and 0 otherwise, and IsPtrXReg is 1 if the pointer register is X.</div><div><br></div><div>I have tried to assign this bit using this expression with macros in AVRInstrInfo.td, but I couldn't get it to compile (!or is not defined, and I don't think macros will solve this situation regardless).</div><div><br></div></div>