2015-09-26 36 views
1

我想添加对llvm backend(llc)中一个新的arch的支持。不过,我发现难以添加一个新的SDNode,它有2个结果。我在UMUL/SMUL有2个结果(第二个是Y)的SPARC弓锯,使他们定义:如何在llvm中构建新的SDNode?

let Defs = [Y] in { 
    defm UMUL : ... 
    defm SMUL : ... 
} 

let Uses = [Y], ... in 
    def RDY : ... 

,并在选择功能,它看起来像:

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

所以他们使用结果1 - 我认为是Y ...


在我的情况下,我有一个影响cc位的指令。 所以我试图用同样的方式。我在Xinstr中定义了:

def SUBCri : ...>{ 
    let Defs = [CRZ]; 
} 

。 。

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

,并在选择功能:

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

,但我得到了一个错误:

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

所以我的问题是:

  1. 什么才是正道定义一个SDNode?
  2. SDVTList VTs是什么意思?这是结果吗? (SDVTList VTs)的顺序是什么意思?
  3. 什么是OpsArray?这是投入吗?插入输入的正确顺序是什么?我看到在“countOperands”函数中,他们检查是否最后一个是胶水。这是什么意思胶水是最后?在同一个函数中,他们检查MVT :: Other是否也存在?这是什么意思 ?
  4. 最后 - 我做错了什么?为什么我不能得到第二个结果?为什么我一直都会遇到这个错误?

回答

2

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

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

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

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

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

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

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

Do do阅读doxygen文档,他们很擅长解释各个功能(即使在大图中缺少一点)。

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