<div dir="ltr">I believe that's done by the "

let Constraints = "$dst = $src2" " here<div><br></div><div>let Constraints = "$dst = $src2" in {<br>let isAsCheapAsAMove = 1 in {<br>  defm ADD : ALU<BPF_ADD, "+=", add>;<br>  defm SUB : ALU<BPF_SUB, "-=", sub>;<br>  defm OR  : ALU<BPF_OR, "|=", or>;<br>  defm AND : ALU<BPF_AND, "&=", and>;<br>  defm SLL : ALU<BPF_LSH, "<<=", shl>;<br>  defm SRL : ALU<BPF_RSH, ">>=", srl>;<br>  defm XOR : ALU<BPF_XOR, "^=", xor>;<br>  defm SRA : ALU<BPF_ARSH, "s>>=", sra>;<br>}<br>  defm MUL : ALU<BPF_MUL, "*=", mul>;<br>  defm DIV : ALU<BPF_DIV, "/=", udiv>;<br>}<br></div><div><br></div><div><br></div><div>As to your second question. I think the register class is only consulted by tablegen to find the type. It's not used to constrain the register class. That's done by the ins/outs of the instruction. So there's probably not difference between GR64 or i64 in this case.</div><div><br></div><div><br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">~Craig</div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, May 12, 2020 at 2:23 PM Chris Sears via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-size:small"><div class="gmail_default">In BPF, an ADD instruction is defined as a 2 register instruction:</div><div class="gmail_default"><br></div><div class="gmail_default">        0x0f.  add dst, src.  dst += src</div><div class="gmail_default"><br></div><div class="gmail_default">In BPFInstrInfo.td this kind of ALU instruction is defined with:</div><div class="gmail_default"><br></div><div class="gmail_default">        def _rr : ALU_RR<BPF_ALU64, Opc,<br>                   (outs GPR:$dst),<br>                   (ins GPR:$src2, GPR:$src),<br>                   "$dst "#OpcodeStr#" $src",<br>                   [(set GPR:$dst, (OpNode i64:$src2, i64:$src))]>;<br></div><div class="gmail_default"><br></div><div class="gmail_default">How does tablegen+codegen ensure that dst and src2 are the same register? I see that the assembly/disassembly string assumes this is the case.</div><div class="gmail_default"><br></div><div class="gmail_default">Also, it uses i64:$src which is an i64 and not a GPR. What is the distinction there? X86 does this differently. src1 and src2 are GR64 registers.</div><div class="gmail_default"><br></div><div class="gmail_default">        def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),<br>                                   (ins GR64:$src1, GR64:$src2),<br>                  "imul{q}\t{$src2, $dst|$dst, $src2}",<br>                  [(set GR64:$dst, EFLAGS,<br>                        (X86smul_flag GR64:$src1, GR64:$src2))]>,<br>                  Sched<[WriteIMul64Reg]>, TB;<br></div><div class="gmail_default"><br></div><font color="#888888"><div class="gmail_default">Chris</div></font></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>