-CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
- : TheDef(R), AsmString(AsmStr) {
- Name = R->getValueAsString("Name");
- Namespace = R->getValueAsString("Namespace");
-
- isReturn = R->getValueAsBit("isReturn");
- isBranch = R->getValueAsBit("isBranch");
- isBarrier = R->getValueAsBit("isBarrier");
- isCall = R->getValueAsBit("isCall");
- isLoad = R->getValueAsBit("isLoad");
- isStore = R->getValueAsBit("isStore");
- isTwoAddress = R->getValueAsBit("isTwoAddress");
- isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
- isCommutable = R->getValueAsBit("isCommutable");
- isTerminator = R->getValueAsBit("isTerminator");
- hasDelaySlot = R->getValueAsBit("hasDelaySlot");
- usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
- hasCtrlDep = R->getValueAsBit("hasCtrlDep");
- noResults = R->getValueAsBit("noResults");
- hasVariableNumberOfOperands = false;
-
- DagInit *DI;
- try {
- DI = R->getValueAsDag("OperandList");
- } catch (...) {
- // Error getting operand list, just ignore it (sparcv9).
- AsmString.clear();
- OperandList.clear();
- return;
- }
-
- unsigned MIOperandNo = 0;
- std::set<std::string> OperandNames;
- for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
- DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i));
- if (!Arg)
- throw "Illegal operand for the '" + R->getName() + "' instruction!";
-
- Record *Rec = Arg->getDef();
- std::string PrintMethod = "printOperand";
- unsigned NumOps = 1;
- DagInit *MIOpInfo = 0;
- if (Rec->isSubClassOf("Operand")) {
- PrintMethod = Rec->getValueAsString("PrintMethod");
- NumOps = Rec->getValueAsInt("NumMIOperands");
- MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
- } else if (Rec->getName() == "variable_ops") {
- hasVariableNumberOfOperands = true;
- continue;
- } else if (!Rec->isSubClassOf("RegisterClass"))
- throw "Unknown operand class '" + Rec->getName() +
- "' in instruction '" + R->getName() + "' instruction!";
-
- // Check that the operand has a name and that it's unique.
- if (DI->getArgName(i).empty())
- throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
- " has no name!";
- if (!OperandNames.insert(DI->getArgName(i)).second)
- throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
- " has the same name as a previous operand!";
-
- OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod,
- MIOperandNo, NumOps, MIOpInfo));
- MIOperandNo += NumOps;
- }
-}
-
-
-
-/// getOperandNamed - Return the index of the operand with the specified
-/// non-empty name. If the instruction does not have an operand with the
-/// specified name, throw an exception.
-///
-unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const {
- assert(!Name.empty() && "Cannot search for operand with no name!");
- for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
- if (OperandList[i].Name == Name) return i;
- throw "Instruction '" + TheDef->getName() +
- "' does not have an operand named '$" + Name + "'!";
-}
-