How do I build a new SDNode in llvm?

yeh*_*ahs 3 llvm llvm-ir

I am trying to add support to a new arch in llvm backend (llc). However I have found it diffcult to add a new SDNode that has 2 results. I saw in the sparc arch that UMUL/SMUL has 2 results (the second is Y) so they defined:

let Defs = [Y] in {
  defm UMUL : ...
  defm SMUL : ...
}
Run Code Online (Sandbox Code Playgroud)

and

let Uses = [Y], ... in
  def RDY : ...
Run Code Online (Sandbox Code Playgroud)

and in the select function it looks like that :

 SDNode *Mul = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::Glue,
                                     MulLHS, MulRHS);
// The high part is in the Y register.
return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDValue(Mul, 1));
Run Code Online (Sandbox Code Playgroud)

so they are using result 1 - I think is the Y...


in my case I have a instruction that affect a cc bit. So I tried to use the same way. I defined in the Xinstr:

def SUBCri : ...>{
  let Defs = [CRZ];
}
Run Code Online (Sandbox Code Playgroud)

. .

let Uses = [CRZ] in {
  def BRC_Z : ... (outs), (ins target:$dst),
}
Run Code Online (Sandbox Code Playgroud)

and in the select function :

    SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::Glue);
    SDNode * CondCode = CurDAG->getMachineNode(X::SUBCri, dl, VTs, ops);
    SDNode * ResNode = CurDAG->SelectNodeTo(Node, X::BRC_Z, MVT::Other, Dst,
            SDValue(CondCode, 1));
Run Code Online (Sandbox Code Playgroud)

but I get the next error :

Assertion `NumMIOperands >= II.getNumOperands() && NumMIOperands <= II.getNumOperands() + II.getNumImplicitDefs() + NumImpUses && "#operands for dag node doesn't match .td file!"' failed.
Run Code Online (Sandbox Code Playgroud)

so my question is :

  1. what is the right way to define a SDNode ?
  2. what SDVTList VTs means ? Is it the results ? what is the order of the (SDVTList VTs) means ?
  3. what are the OpsArray ? is it the inputs ? what is the right order to insert the input ? I saw that in "countOperands" function they check to see if the last one is glue. what does it means the glue is last ? in the same function they check to see if MVT::Other is also exist ? what does it means ?
  4. and finally - what am I doing wrong ? why can't I get the second result ? why am I getting this error all the time ?

Che*_*Sun 5

这真的应该是一个评论,但我没有代表。一些可能有帮助的提示:

  • VT 代表 ValueType。LLVM 需要知道每个 SDNode 的返回值的类型。通过将 VT 传递到 getMachineNode,您可以创建一个新的 SDNode,该 SDNode 返回与 SDVTList 中一样多的具有指定类型的值。

  • “Glue”是一种特殊的 ValueType,它实际上并不包含值。它只是用来确保在指令调度发生时两个粘合的 SDNode 不会分离。

  • “ops”确实是传入的输入。

  • 输入和返回值的顺序应该与 TableGen 中指定的顺序完全一致。

  • 我不确定这一点,但我认为 Defs 不会变成隐式返回值。您可能必须手动创建一个 CopyFromReg 节点,以获取写入的寄存器。

  • MVT::Other 代表一个“链”,一种确保具有副作用的指令不会相对于彼此重新排序的方法。

请阅读 doxygen 文档,它们非常擅长解释各个功能(即使在更大的图景中有点缺乏)。

尝试从这里开始:http : //llvm.org/docs/doxygen/html/classllvm_1_1SelectionDAG.html