<div dir="ltr">llvm-dev,<div><br></div><div style>I'm trying to get a better understanding of sub-registers. I'm seeing the code generator make an odd decision that I was hoping someone could point me in the right direction of explaining.</div>
<div style><br></div><div style>The architecture is 68000, which has 8, 16, and 32 bit views of all of it's data registers. In order to zero extend you can load a big view with zero, and then copy into the small view.</div>
<div style><br></div><div style>I'm working on this llvm function,</div><div style><br></div><div style><div>define i16 @zext_i8_to_i16_simple(i8 %x) {</div><div> %1 = zext i8 %x to i16</div><div> ret i16 %1</div><div>
}</div></div><div style><br></div><div style>I have a pattern where I load the 16 bit portion of the register with 0, and then copy in the 8 bit portion.</div><div style><br></div><div style><div>def : Pat<(i16 (zextloadi8 addr:$src)),</div>
<div> (INSERT_SUBREG (MOV16id 0), (MOV8md addr:$src), sub_byte)>;</div><div><br></div><div style>which produces working but odd assembly,</div><div style><br></div><div style><div>zext_i8_to_i16_simple PROC ; @zext_i8_to_i16_simple</div>
<div>; BB#0:</div><div> move.b 4(a7), d1</div><div> move.w #0, d0</div><div> move.b d1, d0</div><div> rts</div><div><br></div><div style>Notice the extraneous use of d1, as</div><div style><br>
</div><div style>move.w #0, d0</div><div style>move.b 4(a7), d0</div><div style><br></div><div style>would work just as well.</div><div style><br></div><div style>If however, I load the 32 bit portion of the register with 0, truncate it to 16bits, and then copy in the 8 bit portion, I get what I expect.</div>
<div style><br></div><div style><div>def : Pat<(i16 (zextloadi8 addr:$src)),</div><div> (INSERT_SUBREG (EXTRACT_SUBREG (MOVQ32 0), sub_word),</div><div> (MOV8md addr:$src),</div><div> sub_byte)>;</div>
<div><br></div><div><div>zext_i8_to_i16_simple PROC ; @zext_i8_to_i16_simple</div><div>; BB#0:</div><div> moveq #0, d0</div><div> move.b 4(a7), d0</div><div> rts<br></div></div><div><br>
</div><div style>I'm building off of the llvm 3.2 release, if it matters. I'm mostly looking for where to look to understand what's going on and/or extra documentation on how subregisters work inside the instruction and registers selectors.</div>
<div><br></div><div style>Thank you,</div><div style>-- Kenneth Waters</div><div style><br></div><div style>P.S. If it helps, my register definitions look like,</div><div style><br></div><div style><div>multiclass M68kDataReg<bits<3> num, string defn, string n> {</div>
<div> def B : M68kReg<num, n>;</div><div> def W : M68kRegWithSubregs<num, n, [!cast<Register>(defn # "B")]> {</div><div> let SubRegIndices = [sub_byte];</div><div> }</div><div> def L : M68kRegWithSubregs<num, n, [!cast<Register>(defn # "W")]> {</div>
<div> let SubRegIndices = [sub_word];</div><div> }</div><div>}</div><div><div>defm D0 : M68kDataReg<0, "D0", "d0">;</div></div><div><div>defm D1 : M68kDataReg<1, "D1", "d1">;</div>
</div></div></div></div></div></div>