<div dir="ltr"><div class="gmail_extra"></div><div class="gmail_extra"><div class="gmail_quote">On 28 July 2017 at 12:08, Matthias Braun <span dir="ltr"><<a href="mailto:mbraun@apple.com" target="_blank">mbraun@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><span class=""><blockquote type="cite"><div>On Jul 27, 2017, at 10:47 PM, Arvind <<a href="mailto:sraj.arvind@gmail.com" target="_blank">sraj.arvind@gmail.com</a>> wrote:</div><br class="m_-300366215634681647Apple-interchange-newline"><div><div dir="ltr"><div class="gmail_extra">Hello Matthias,<br><br></div><div class="gmail_extra"><div class="gmail_quote">On 28 July 2017 at 04:13, Matthias Braun <span dir="ltr"><<a href="mailto:mbraun@apple.com" target="_blank">mbraun@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It's not that hard in principle:<br>
- A register class is a set of registers.<br>
- Virtual Registers have a register class assigned.<br>
- If you have register constraints (like x86 8bit operations only work on al,ah,etc.) then you have to create a new register class to express that. (The only exception being limited to a single register, which instead we express by assigning the physreg directly instead of using a vreg).<br>
- Tablegen may create more regsiter classes for register coalescing where we want to accomodate constraints of multiple instructions at the same time.<br>
- All the information is in the .td file; you just have to put some effort into learning tablegen as the information is often expressed by using functions (i.e. the use add/sub/rotate/etc.) instead of just writing a table/list of registers).<br></blockquote><div><br></div><div>Thanks a lot for the response! The TableGen language is fairly straightforward(at least commands used in X86 td file). However, some of the comments about the classes didn't fully make sense: I suppose the constraints are probably derived from the X86 assembly language and I should look there? In addition, some classes don't have any comments(eg: GR64_TCW64) and I couldn't find much info elsewhere.<br></div></div></div></div></div></blockquote></span><div>The GR64_TCW64 class doesn’t seem to be used in an instruction but for modeling an ABI constraint. Search the sourcecode you will find the only user:</div><div><br></div><div><div>const TargetRegisterClass *</div><div>X86RegisterInfo::<wbr>getGPRsForTailCall(const MachineFunction &MF) const {</div><div>  const Function *F = MF.getFunction();</div><div>  if (IsWin64 || (F && F->getCallingConv() == CallingConv::Win64))</div><div>    return &X86::GR64_TCW64RegClass;</div><div>…</div><div>(And I can’t tell you much more about; I don’t know windows ABIs)</div></div></div></div></blockquote><div><br></div><div>Ah I see. Thanks for the explanations and tips Matthias and Craig! I will inspect the source code to figure things out and ask again if I'm stuck somewhere specifically.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div><br></div></div><span class=""><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br>Also, I don't know how the TableGen'erated classes are derived. Would reading TableGen's code help understand why those were generated and what constraints they encode? Or should I take another approach?<br></div></div></div></div>
</div></blockquote></span></div><br><div>You probably have to read the tablegen source to see everything. I can attempt to explain typical cases:</div><div><br></div><div>* Common Sub Classes: For example when you need a vreg that works for both an GR32_NOAX and an GR32_NOSP operand at the same time, then you would need a class that contains GR32 without eax and without nosp. As that class is not defined the tablegen file itself but someone could be calling TargetRegisterInfo::<wbr>getCommonSubClass(GR32_NOAX, GR32_NOSP) tablegen will precompute it and give it a name like “GR32_NOAX_and_GR32_NOSP”.</div><div>* Similar for TargetRegisterInfo::<wbr>getSubClassWithSubReg which returns a subclass containing all registers that support a specific subregister index. Again tablegen precompute all possible combinations and gives it a name like “GR64_with_sub_8bitReg”.</div></div></blockquote><div><br></div><div> Thanks for this example - helps clear few things up! I will dive into TableGen's code to understand the complete picture.<br></div></div><br></div></div>