+/// 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,
+ MatchableInfo::AsmOperand &Op) {
+ StringRef Token = Op.Token;
+ assert(Token[0] == '$' && "Not an operand name ref");
+
+ StringRef OperandName;
+ if (Token[1] == '{')
+ OperandName = Token.substr(2, Token.size() - 3);
+ else
+ OperandName = Token.substr(1);
+
+ const CGIOperandList &Operands = II->TheOperandList;
+
+
+ // Map this token to an operand. FIXME: Move elsewhere.
+ unsigned Idx;
+ if (!Operands.hasOperandNamed(OperandName, Idx))
+ throw TGError(II->TheDef->getLoc(), "error: unable to find operand: '" +
+ OperandName.str() + "'");
+
+ // FIXME: This is annoying, the named operand may be tied (e.g.,
+ // XCHG8rm). What we want is the untied operand, which we now have to
+ // grovel for. Only worry about this for single entry operands, we have to
+ // clean this up anyway.
+ const CGIOperandList::OperandInfo *OI = &Operands[Idx];
+ int OITied = OI->getTiedRegister();
+ if (OITied != -1) {
+ // The tied operand index is an MIOperand index, find the operand that
+ // contains it.
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+ if (Operands[i].MIOperandNo == unsigned(OITied)) {
+ OI = &Operands[i];
+ break;
+ }
+ }
+
+ assert(OI && "Unable to find tied operand target!");
+ }
+
+ Op.Class = getOperandClass(Token, *OI);
+ Op.OperandInfo = OI;
+}
+