+/// BuildInstructionOperandReference - The specified operand is a reference to a
+/// named operand such as $src. Resolve the Class and OperandInfo pointers.
+void AsmMatcherInfo::
+BuildInstructionOperandReference(MatchableInfo *II,
+ StringRef OperandName,
+ unsigned AsmOpIdx) {
+ const CodeGenInstruction &CGI = *II->DefRec.get<const CodeGenInstruction*>();
+ const CGIOperandList &Operands = CGI.Operands;
+ MatchableInfo::AsmOperand *Op = &II->AsmOperands[AsmOpIdx];
+
+ // Map this token to an operand.
+ unsigned Idx;
+ if (!Operands.hasOperandNamed(OperandName, Idx))
+ throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
+ OperandName.str() + "'");
+
+ // If the instruction operand has multiple suboperands, but the parser
+ // match class for the asm operand is still the default "ImmAsmOperand",
+ // then handle each suboperand separately.
+ if (Op->SubOpIdx == -1 && Operands[Idx].MINumOperands > 1) {
+ Record *Rec = Operands[Idx].Rec;
+ assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
+ Record *MatchClass = Rec->getValueAsDef("ParserMatchClass");
+ if (MatchClass && MatchClass->getValueAsString("Name") == "Imm") {
+ // Insert remaining suboperands after AsmOpIdx in II->AsmOperands.
+ StringRef Token = Op->Token; // save this in case Op gets moved
+ for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) {
+ MatchableInfo::AsmOperand NewAsmOp(Token);
+ NewAsmOp.SubOpIdx = SI;
+ II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp);
+ }
+ // Replace Op with first suboperand.
+ Op = &II->AsmOperands[AsmOpIdx]; // update the pointer in case it moved
+ Op->SubOpIdx = 0;
+ }
+ }
+
+ // Set up the operand class.
+ Op->Class = getOperandClass(Operands[Idx], Op->SubOpIdx);
+
+ // If the named operand is tied, canonicalize it to the untied operand.
+ // For example, something like:
+ // (outs GPR:$dst), (ins GPR:$src)
+ // with an asmstring of
+ // "inc $src"
+ // we want to canonicalize to:
+ // "inc $dst"
+ // so that we know how to provide the $dst operand when filling in the result.
+ int OITied = Operands[Idx].getTiedRegister();
+ if (OITied != -1) {
+ // The tied operand index is an MIOperand index, find the operand that
+ // contains it.
+ std::pair<unsigned, unsigned> Idx = Operands.getSubOperandNumber(OITied);
+ OperandName = Operands[Idx.first].Name;
+ Op->SubOpIdx = Idx.second;
+ }
+
+ Op->SrcOpName = OperandName;
+}
+
+/// BuildAliasOperandReference - When parsing an operand reference out of the
+/// matching string (e.g. "movsx $src, $dst"), determine what the class of the
+/// operand reference is by looking it up in the result pattern definition.
+void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
+ StringRef OperandName,
+ MatchableInfo::AsmOperand &Op) {
+ const CodeGenInstAlias &CGA = *II->DefRec.get<const CodeGenInstAlias*>();
+
+ // Set up the operand class.
+ for (unsigned i = 0, e = CGA.ResultOperands.size(); i != e; ++i)
+ if (CGA.ResultOperands[i].isRecord() &&
+ CGA.ResultOperands[i].getName() == OperandName) {
+ // It's safe to go with the first one we find, because CodeGenInstAlias
+ // validates that all operands with the same name have the same record.
+ unsigned ResultIdx = CGA.ResultInstOperandIndex[i].first;
+ Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second;
+ Op.Class = getOperandClass(CGA.ResultInst->Operands[ResultIdx],
+ Op.SubOpIdx);
+ Op.SrcOpName = OperandName;
+ return;
+ }
+
+ throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
+ OperandName.str() + "'");
+}
+
+void MatchableInfo::BuildInstructionResultOperands() {
+ const CodeGenInstruction *ResultInst = getResultInst();
+
+ // Loop over all operands of the result instruction, determining how to
+ // populate them.
+ for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
+ const CGIOperandList::OperandInfo &OpInfo = ResultInst->Operands[i];
+
+ // If this is a tied operand, just copy from the previously handled operand.
+ int TiedOp = OpInfo.getTiedRegister();
+ if (TiedOp != -1) {
+ ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
+ continue;
+ }
+
+ // Find out what operand from the asmparser this MCInst operand comes from.
+ int SrcOperand = FindAsmOperandNamed(OpInfo.Name);
+ if (OpInfo.Name.empty() || SrcOperand == -1)
+ throw TGError(TheDef->getLoc(), "Instruction '" +
+ TheDef->getName() + "' has operand '" + OpInfo.Name +
+ "' that doesn't appear in asm string!");
+
+ // Check if the one AsmOperand populates the entire operand.
+ unsigned NumOperands = OpInfo.MINumOperands;
+ if (AsmOperands[SrcOperand].SubOpIdx == -1) {
+ ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand, NumOperands));
+ continue;
+ }
+
+ // Add a separate ResOperand for each suboperand.
+ for (unsigned AI = 0; AI < NumOperands; ++AI) {
+ assert(AsmOperands[SrcOperand+AI].SubOpIdx == (int)AI &&
+ AsmOperands[SrcOperand+AI].SrcOpName == OpInfo.Name &&
+ "unexpected AsmOperands for suboperands");
+ ResOperands.push_back(ResOperand::getRenderedOp(SrcOperand + AI, 1));
+ }
+ }
+}
+
+void MatchableInfo::BuildAliasResultOperands() {
+ const CodeGenInstAlias &CGA = *DefRec.get<const CodeGenInstAlias*>();
+ const CodeGenInstruction *ResultInst = getResultInst();
+
+ // Loop over all operands of the result instruction, determining how to
+ // populate them.
+ unsigned AliasOpNo = 0;
+ unsigned LastOpNo = CGA.ResultInstOperandIndex.size();
+ for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
+ const CGIOperandList::OperandInfo *OpInfo = &ResultInst->Operands[i];
+
+ // If this is a tied operand, just copy from the previously handled operand.
+ int TiedOp = OpInfo->getTiedRegister();
+ if (TiedOp != -1) {
+ ResOperands.push_back(ResOperand::getTiedOp(TiedOp));
+ continue;
+ }