<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>