Я пытаюсь добавить поддержку новой арки в бэкэнде llvm (llc). Однако мне было сложно добавить новый SDNode, который имеет 2 результата. Я видел в арке sparc, что UMUL/SMUL имеет 2 результата (второй Y), поэтому они определили:
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.
поэтому мой вопрос:
- как правильно определить SDNode?
- что означает SDVTList VTs? Это результаты? что означает порядок (SDVTList VTs)?
- что такое OpsArray? это входы? каков правильный порядок вставки ввода? Я видел, что в функции countOperands они проверяют, является ли последний клеем. что значит клей последний? в той же функции они проверяют, существует ли MVT::Other? что это значит ?
- и наконец - что я делаю не так? почему я не могу получить второй результат? почему я постоянно получаю эту ошибку?