| Chris Lattner | 33ccf7e | 2003-08-03 17:24:10 +0000 | [diff] [blame] | 1 | //===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// | 
| Misha Brukman | 3da94ae | 2005-04-22 00:00:37 +0000 | [diff] [blame] | 2 | // | 
| John Criswell | 01d4582 | 2003-10-20 20:20:30 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file was developed by the LLVM research group and is distributed under | 
 | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
| Misha Brukman | 3da94ae | 2005-04-22 00:00:37 +0000 | [diff] [blame] | 7 | // | 
| John Criswell | 01d4582 | 2003-10-20 20:20:30 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 33ccf7e | 2003-08-03 17:24:10 +0000 | [diff] [blame] | 9 | // | 
 | 10 | // This tablegen backend is responsible for emitting a description of the target | 
 | 11 | // instruction set for the code generator. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
 | 15 | #include "InstrInfoEmitter.h" | 
| Chris Lattner | 803a5f6 | 2004-08-01 04:04:35 +0000 | [diff] [blame] | 16 | #include "CodeGenTarget.h" | 
| Chris Lattner | 33ccf7e | 2003-08-03 17:24:10 +0000 | [diff] [blame] | 17 | #include "Record.h" | 
| Jeff Cohen | cb366d9 | 2005-11-01 18:04:06 +0000 | [diff] [blame] | 18 | #include <algorithm> | 
| Chris Lattner | 2082ebe | 2004-08-01 03:55:39 +0000 | [diff] [blame] | 19 | using namespace llvm; | 
| Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 20 |  | 
| Chris Lattner | 33ccf7e | 2003-08-03 17:24:10 +0000 | [diff] [blame] | 21 | // runEnums - Print out enum values for all of the instructions. | 
 | 22 | void InstrInfoEmitter::runEnums(std::ostream &OS) { | 
| Chris Lattner | bc01723 | 2003-08-06 04:32:07 +0000 | [diff] [blame] | 23 |   EmitSourceFileHeader("Target Instruction Enum Values", OS); | 
| Chris Lattner | 2c38413 | 2004-08-17 03:08:28 +0000 | [diff] [blame] | 24 |   OS << "namespace llvm {\n\n"; | 
| Chris Lattner | 33ccf7e | 2003-08-03 17:24:10 +0000 | [diff] [blame] | 25 |  | 
| Chris Lattner | 7884b75 | 2003-08-07 05:39:09 +0000 | [diff] [blame] | 26 |   CodeGenTarget Target; | 
 | 27 |  | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 28 |   // We must emit the PHI opcode first... | 
| Chris Lattner | eff5c36 | 2006-05-01 23:46:16 +0000 | [diff] [blame] | 29 |   std::string Namespace; | 
 | 30 |   for (CodeGenTarget::inst_iterator II = Target.inst_begin(),  | 
 | 31 |        E = Target.inst_end(); II != E; ++II) { | 
 | 32 |     if (II->second.Namespace != "TargetInstrInfo") { | 
 | 33 |       Namespace = II->second.Namespace; | 
 | 34 |       break; | 
 | 35 |     } | 
 | 36 |   } | 
 | 37 |    | 
 | 38 |   if (Namespace.empty()) { | 
 | 39 |     std::cerr << "No instructions defined!\n"; | 
 | 40 |     exit(1); | 
 | 41 |   } | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 42 |  | 
| Chris Lattner | d648867 | 2005-01-22 18:58:51 +0000 | [diff] [blame] | 43 |   std::vector<const CodeGenInstruction*> NumberedInstructions; | 
 | 44 |   Target.getInstructionsByEnumValue(NumberedInstructions); | 
 | 45 |  | 
| Chris Lattner | eff5c36 | 2006-05-01 23:46:16 +0000 | [diff] [blame] | 46 |   OS << "namespace " << Namespace << " {\n"; | 
 | 47 |   OS << "  enum {\n"; | 
| Chris Lattner | d648867 | 2005-01-22 18:58:51 +0000 | [diff] [blame] | 48 |   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { | 
 | 49 |     OS << "    " << NumberedInstructions[i]->TheDef->getName() | 
| Chris Lattner | eff5c36 | 2006-05-01 23:46:16 +0000 | [diff] [blame] | 50 |        << "\t= " << i << ",\n"; | 
| Chris Lattner | d648867 | 2005-01-22 18:58:51 +0000 | [diff] [blame] | 51 |   } | 
| Chris Lattner | eff5c36 | 2006-05-01 23:46:16 +0000 | [diff] [blame] | 52 |   OS << "    INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; | 
 | 53 |   OS << "  };\n}\n"; | 
| Chris Lattner | 2c38413 | 2004-08-17 03:08:28 +0000 | [diff] [blame] | 54 |   OS << "} // End llvm namespace \n"; | 
| Chris Lattner | 33ccf7e | 2003-08-03 17:24:10 +0000 | [diff] [blame] | 55 | } | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 56 |  | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 57 | void InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses, | 
 | 58 |                                     unsigned Num, std::ostream &OS) const { | 
 | 59 |   OS << "static const unsigned ImplicitList" << Num << "[] = { "; | 
 | 60 |   for (unsigned i = 0, e = Uses.size(); i != e; ++i) | 
 | 61 |     OS << getQualifiedName(Uses[i]) << ", "; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 62 |   OS << "0 };\n"; | 
 | 63 | } | 
 | 64 |  | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 65 | static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) { | 
 | 66 |   std::vector<Record*> Result; | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 67 |   for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) { | 
| Chris Lattner | 65303d6 | 2005-11-19 07:05:57 +0000 | [diff] [blame] | 68 |     if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) { | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 69 |       Result.push_back(Inst.OperandList[i].Rec); | 
| Chris Lattner | 65303d6 | 2005-11-19 07:05:57 +0000 | [diff] [blame] | 70 |     } else { | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 71 |       // This might be a multiple operand thing. | 
| Chris Lattner | 65303d6 | 2005-11-19 07:05:57 +0000 | [diff] [blame] | 72 |       // Targets like X86 have registers in their multi-operand operands. | 
 | 73 |       DagInit *MIOI = Inst.OperandList[i].MIOperandInfo; | 
 | 74 |       unsigned NumDefs = MIOI->getNumArgs(); | 
 | 75 |       for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) { | 
 | 76 |         if (NumDefs <= j) { | 
 | 77 |           Result.push_back(0); | 
 | 78 |         } else { | 
 | 79 |           DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j)); | 
 | 80 |           Result.push_back(Def ? Def->getDef() : 0); | 
 | 81 |         } | 
 | 82 |       } | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 83 |     } | 
 | 84 |   } | 
 | 85 |   return Result; | 
 | 86 | } | 
 | 87 |  | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 88 |  | 
 | 89 | // run - Emit the main instruction description records for the target... | 
 | 90 | void InstrInfoEmitter::run(std::ostream &OS) { | 
| Jim Laskey | b5a0c0e | 2005-10-31 17:16:46 +0000 | [diff] [blame] | 91 |   GatherItinClasses(); | 
 | 92 |  | 
| Chris Lattner | bc01723 | 2003-08-06 04:32:07 +0000 | [diff] [blame] | 93 |   EmitSourceFileHeader("Target Instruction Descriptors", OS); | 
| Chris Lattner | 2c38413 | 2004-08-17 03:08:28 +0000 | [diff] [blame] | 94 |   OS << "namespace llvm {\n\n"; | 
 | 95 |  | 
| Chris Lattner | 7884b75 | 2003-08-07 05:39:09 +0000 | [diff] [blame] | 96 |   CodeGenTarget Target; | 
 | 97 |   const std::string &TargetName = Target.getName(); | 
 | 98 |   Record *InstrInfo = Target.getInstructionSet(); | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 99 |  | 
| Alkis Evlogimenos | 73ff512 | 2003-10-08 05:20:08 +0000 | [diff] [blame] | 100 |   // Emit empty implicit uses and defs lists | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 101 |   OS << "static const unsigned EmptyImpList[] = { 0 };\n"; | 
| Alkis Evlogimenos | 73ff512 | 2003-10-08 05:20:08 +0000 | [diff] [blame] | 102 |  | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 103 |   // Keep track of all of the def lists we have emitted already. | 
 | 104 |   std::map<std::vector<Record*>, unsigned> EmittedLists; | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 105 |   unsigned ListNumber = 0; | 
 | 106 |   | 
 | 107 |   // Emit all of the instruction's implicit uses and defs. | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 108 |   for (CodeGenTarget::inst_iterator II = Target.inst_begin(), | 
 | 109 |          E = Target.inst_end(); II != E; ++II) { | 
 | 110 |     Record *Inst = II->second.TheDef; | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 111 |     std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); | 
 | 112 |     if (!Uses.empty()) { | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 113 |       unsigned &IL = EmittedLists[Uses]; | 
 | 114 |       if (!IL) printDefList(Uses, IL = ++ListNumber, OS); | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 115 |     } | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 116 |     std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); | 
 | 117 |     if (!Defs.empty()) { | 
 | 118 |       unsigned &IL = EmittedLists[Defs]; | 
 | 119 |       if (!IL) printDefList(Defs, IL = ++ListNumber, OS); | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 120 |     } | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 121 |   } | 
 | 122 |  | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 123 |   std::map<std::vector<Record*>, unsigned> OperandInfosEmitted; | 
 | 124 |   unsigned OperandListNum = 0; | 
 | 125 |   OperandInfosEmitted[std::vector<Record*>()] = ++OperandListNum; | 
 | 126 |    | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 127 |   // Emit all of the operand info records. | 
 | 128 |   OS << "\n"; | 
 | 129 |   for (CodeGenTarget::inst_iterator II = Target.inst_begin(), | 
 | 130 |        E = Target.inst_end(); II != E; ++II) { | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 131 |     std::vector<Record*> OperandInfo = GetOperandInfo(II->second); | 
 | 132 |     unsigned &N = OperandInfosEmitted[OperandInfo]; | 
 | 133 |     if (N == 0) { | 
 | 134 |       N = ++OperandListNum; | 
 | 135 |       OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { "; | 
 | 136 |       for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) { | 
| Chris Lattner | 65303d6 | 2005-11-19 07:05:57 +0000 | [diff] [blame] | 137 |         Record *RC = OperandInfo[i]; | 
 | 138 |         // FIXME: We only care about register operands for now. | 
| Evan Cheng | 21d03f2 | 2006-05-18 20:42:07 +0000 | [diff] [blame] | 139 |         if (RC && RC->isSubClassOf("RegisterClass")) | 
 | 140 |           OS << "{ &" << getQualifiedName(RC) << "RegClass, 0 }, "; | 
 | 141 |         else if (RC && RC->getName() == "ptr_rc") | 
 | 142 |           // Ptr value whose register class is resolved via callback. | 
 | 143 |           OS << "{ 0, 1 }, "; | 
 | 144 |         else | 
 | 145 |           OS << "{ 0, 0 }, "; | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 146 |       } | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 147 |       OS << "};\n"; | 
 | 148 |     } | 
 | 149 |   } | 
 | 150 |    | 
| Chris Lattner | f52e261 | 2006-01-27 01:44:09 +0000 | [diff] [blame] | 151 |   // Emit all of the TargetInstrDescriptor records in their ENUM ordering. | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 152 |   // | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 153 |   OS << "\nstatic const TargetInstrDescriptor " << TargetName | 
 | 154 |      << "Insts[] = {\n"; | 
| Chris Lattner | f52e261 | 2006-01-27 01:44:09 +0000 | [diff] [blame] | 155 |   std::vector<const CodeGenInstruction*> NumberedInstructions; | 
 | 156 |   Target.getInstructionsByEnumValue(NumberedInstructions); | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 157 |  | 
| Chris Lattner | f52e261 | 2006-01-27 01:44:09 +0000 | [diff] [blame] | 158 |   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) | 
 | 159 |     emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, | 
 | 160 |                OperandInfosEmitted, OS); | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 161 |   OS << "};\n"; | 
| Chris Lattner | 2c38413 | 2004-08-17 03:08:28 +0000 | [diff] [blame] | 162 |   OS << "} // End llvm namespace \n"; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 163 | } | 
 | 164 |  | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 165 | void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 166 |                                   Record *InstrInfo, | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 167 |                          std::map<std::vector<Record*>, unsigned> &EmittedLists, | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 168 |                                std::map<std::vector<Record*>, unsigned> &OpInfo, | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 169 |                                   std::ostream &OS) { | 
| Evan Cheng | 8d3af5e | 2006-06-15 07:22:16 +0000 | [diff] [blame] | 170 |   int MinOperands; | 
 | 171 |   if (!Inst.OperandList.empty()) | 
| Chris Lattner | d98958f | 2005-08-19 00:59:49 +0000 | [diff] [blame] | 172 |     // Each logical operand can be multiple MI operands. | 
| Evan Cheng | 8d3af5e | 2006-06-15 07:22:16 +0000 | [diff] [blame] | 173 |     MinOperands = Inst.OperandList.back().MIOperandNo + | 
| Chris Lattner | d98958f | 2005-08-19 00:59:49 +0000 | [diff] [blame] | 174 |                   Inst.OperandList.back().MINumOperands; | 
 | 175 |   else | 
| Evan Cheng | 8d3af5e | 2006-06-15 07:22:16 +0000 | [diff] [blame] | 176 |     MinOperands = 0; | 
| Chris Lattner | d98958f | 2005-08-19 00:59:49 +0000 | [diff] [blame] | 177 |    | 
| Chris Lattner | 2d12b2c | 2004-08-01 08:38:17 +0000 | [diff] [blame] | 178 |   OS << "  { \""; | 
 | 179 |   if (Inst.Name.empty()) | 
 | 180 |     OS << Inst.TheDef->getName(); | 
 | 181 |   else | 
 | 182 |     OS << Inst.Name; | 
| Jim Laskey | b5a0c0e | 2005-10-31 17:16:46 +0000 | [diff] [blame] | 183 |    | 
 | 184 |   unsigned ItinClass = !IsItineraries ? 0 : | 
 | 185 |             ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName()); | 
 | 186 |    | 
| Evan Cheng | 8d3af5e | 2006-06-15 07:22:16 +0000 | [diff] [blame] | 187 |   OS << "\",\t" << MinOperands << ", " << ItinClass | 
| Jim Laskey | b5a0c0e | 2005-10-31 17:16:46 +0000 | [diff] [blame] | 188 |      << ", 0"; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 189 |  | 
| Evan Cheng | 6f6360d | 2006-05-01 09:04:20 +0000 | [diff] [blame] | 190 |   // Try to determine (from the pattern), if the instruction is a store. | 
 | 191 |   bool isStore = false; | 
 | 192 |   if (dynamic_cast<ListInit*>(Inst.TheDef->getValueInit("Pattern"))) { | 
 | 193 |     ListInit *LI = Inst.TheDef->getValueAsListInit("Pattern"); | 
 | 194 |     if (LI && LI->getSize() > 0) { | 
 | 195 |       DagInit *Dag = (DagInit *)LI->getElement(0); | 
 | 196 |       DefInit *OpDef = dynamic_cast<DefInit*>(Dag->getOperator()); | 
 | 197 |       if (OpDef) { | 
 | 198 |         Record *Operator = OpDef->getDef(); | 
| Evan Cheng | 108714c | 2006-05-03 02:08:34 +0000 | [diff] [blame] | 199 |         if (Operator->isSubClassOf("SDNode")) { | 
 | 200 |           const std::string Opcode = Operator->getValueAsString("Opcode"); | 
 | 201 |           if (Opcode == "ISD::STORE" || Opcode == "ISD::TRUNCSTORE") | 
 | 202 |             isStore = true; | 
 | 203 |         } | 
| Evan Cheng | 6f6360d | 2006-05-01 09:04:20 +0000 | [diff] [blame] | 204 |       } | 
 | 205 |     } | 
 | 206 |   } | 
 | 207 |  | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 208 |   // Emit all of the target indepedent flags... | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 209 |   if (Inst.isReturn)     OS << "|M_RET_FLAG"; | 
 | 210 |   if (Inst.isBranch)     OS << "|M_BRANCH_FLAG"; | 
 | 211 |   if (Inst.isBarrier)    OS << "|M_BARRIER_FLAG"; | 
| Chris Lattner | 5b71d3a | 2004-09-28 18:38:01 +0000 | [diff] [blame] | 212 |   if (Inst.hasDelaySlot) OS << "|M_DELAY_SLOT_FLAG"; | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 213 |   if (Inst.isCall)       OS << "|M_CALL_FLAG"; | 
| Nate Begeman | cdd66b5 | 2004-09-28 21:01:45 +0000 | [diff] [blame] | 214 |   if (Inst.isLoad)       OS << "|M_LOAD_FLAG"; | 
| Evan Cheng | 6f6360d | 2006-05-01 09:04:20 +0000 | [diff] [blame] | 215 |   if (Inst.isStore || isStore) OS << "|M_STORE_FLAG"; | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 216 |   if (Inst.isTwoAddress) OS << "|M_2_ADDR_FLAG"; | 
| Chris Lattner | aad75aa | 2005-01-02 02:29:04 +0000 | [diff] [blame] | 217 |   if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR"; | 
 | 218 |   if (Inst.isCommutable) OS << "|M_COMMUTABLE"; | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 219 |   if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG"; | 
| Chris Lattner | 5f89bf0 | 2005-08-26 20:42:52 +0000 | [diff] [blame] | 220 |   if (Inst.usesCustomDAGSchedInserter) | 
| Chris Lattner | 8b50f9b | 2005-08-26 20:40:46 +0000 | [diff] [blame] | 221 |     OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION"; | 
| Evan Cheng | 8d3af5e | 2006-06-15 07:22:16 +0000 | [diff] [blame] | 222 |   if (Inst.hasVariableNumberOfOperands) | 
 | 223 |     OS << "|M_VARIABLE_OPS"; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 224 |   OS << ", 0"; | 
 | 225 |  | 
 | 226 |   // Emit all of the target-specific flags... | 
 | 227 |   ListInit *LI    = InstrInfo->getValueAsListInit("TSFlagsFields"); | 
 | 228 |   ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); | 
 | 229 |   if (LI->getSize() != Shift->getSize()) | 
 | 230 |     throw "Lengths of " + InstrInfo->getName() + | 
 | 231 |           ":(TargetInfoFields, TargetInfoPositions) must be equal!"; | 
 | 232 |  | 
 | 233 |   for (unsigned i = 0, e = LI->getSize(); i != e; ++i) | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 234 |     emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)), | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 235 |                      dynamic_cast<IntInit*>(Shift->getElement(i)), OS); | 
 | 236 |  | 
 | 237 |   OS << ", "; | 
 | 238 |  | 
 | 239 |   // Emit the implicit uses and defs lists... | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 240 |   std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); | 
 | 241 |   if (UseList.empty()) | 
| Chris Lattner | a3ac88d | 2005-08-18 21:36:47 +0000 | [diff] [blame] | 242 |     OS << "EmptyImpList, "; | 
| Misha Brukman | 3da94ae | 2005-04-22 00:00:37 +0000 | [diff] [blame] | 243 |   else | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 244 |     OS << "ImplicitList" << EmittedLists[UseList] << ", "; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 245 |  | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 246 |   std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); | 
 | 247 |   if (DefList.empty()) | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 248 |     OS << "EmptyImpList, "; | 
| Misha Brukman | 3da94ae | 2005-04-22 00:00:37 +0000 | [diff] [blame] | 249 |   else | 
| Chris Lattner | 366080c | 2005-10-28 22:59:53 +0000 | [diff] [blame] | 250 |     OS << "ImplicitList" << EmittedLists[DefList] << ", "; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 251 |  | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 252 |   // Emit the operand info. | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 253 |   std::vector<Record*> OperandInfo = GetOperandInfo(Inst); | 
 | 254 |   if (OperandInfo.empty()) | 
 | 255 |     OS << "0"; | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 256 |   else | 
| Chris Lattner | d5aa3e2 | 2005-08-19 18:46:26 +0000 | [diff] [blame] | 257 |     OS << "OperandInfo" << OpInfo[OperandInfo]; | 
| Chris Lattner | 0e384b6 | 2005-08-19 16:57:28 +0000 | [diff] [blame] | 258 |    | 
| Chris Lattner | ec35240 | 2004-08-01 05:04:00 +0000 | [diff] [blame] | 259 |   OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 260 | } | 
 | 261 |  | 
| Jim Laskey | b5a0c0e | 2005-10-31 17:16:46 +0000 | [diff] [blame] | 262 | struct LessRecord { | 
 | 263 |   bool operator()(const Record *Rec1, const Record *Rec2) const { | 
 | 264 |     return Rec1->getName() < Rec2->getName(); | 
 | 265 |   } | 
 | 266 | }; | 
 | 267 | void InstrInfoEmitter::GatherItinClasses() { | 
 | 268 |   std::vector<Record*> DefList = | 
 | 269 |                           Records.getAllDerivedDefinitions("InstrItinClass"); | 
 | 270 |   IsItineraries = !DefList.empty(); | 
 | 271 |    | 
 | 272 |   if (!IsItineraries) return; | 
 | 273 |    | 
| Duraid Madina | 42d24c7 | 2005-12-30 14:56:37 +0000 | [diff] [blame] | 274 |   std::sort(DefList.begin(), DefList.end(), LessRecord()); | 
| Jim Laskey | b5a0c0e | 2005-10-31 17:16:46 +0000 | [diff] [blame] | 275 |  | 
 | 276 |   for (unsigned i = 0, N = DefList.size(); i < N; i++) { | 
 | 277 |     Record *Def = DefList[i]; | 
| Jim Laskey | 6cee630 | 2005-11-01 20:06:59 +0000 | [diff] [blame] | 278 |     ItinClassMap[Def->getName()] = i; | 
| Jim Laskey | b5a0c0e | 2005-10-31 17:16:46 +0000 | [diff] [blame] | 279 |   } | 
 | 280 | }   | 
 | 281 |    | 
 | 282 | unsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) { | 
 | 283 |   return ItinClassMap[ItinName]; | 
 | 284 | } | 
 | 285 |  | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 286 | void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, | 
 | 287 |                                         IntInit *ShiftInt, std::ostream &OS) { | 
 | 288 |   if (Val == 0 || ShiftInt == 0) | 
 | 289 |     throw std::string("Illegal value or shift amount in TargetInfo*!"); | 
 | 290 |   RecordVal *RV = R->getValue(Val->getValue()); | 
 | 291 |   int Shift = ShiftInt->getValue(); | 
 | 292 |  | 
| Chris Lattner | f52e261 | 2006-01-27 01:44:09 +0000 | [diff] [blame] | 293 |   if (RV == 0 || RV->getValue() == 0) { | 
 | 294 |     // This isn't an error if this is a builtin instruction. | 
 | 295 |     if (R->getName() != "PHI" && R->getName() != "INLINEASM") | 
 | 296 |       throw R->getName() + " doesn't have a field named '" +  | 
 | 297 |             Val->getValue() + "'!"; | 
 | 298 |     return; | 
 | 299 |   } | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 300 |  | 
 | 301 |   Init *Value = RV->getValue(); | 
 | 302 |   if (BitInit *BI = dynamic_cast<BitInit*>(Value)) { | 
 | 303 |     if (BI->getValue()) OS << "|(1<<" << Shift << ")"; | 
 | 304 |     return; | 
 | 305 |   } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) { | 
 | 306 |     // Convert the Bits to an integer to print... | 
 | 307 |     Init *I = BI->convertInitializerTo(new IntRecTy()); | 
 | 308 |     if (I) | 
 | 309 |       if (IntInit *II = dynamic_cast<IntInit*>(I)) { | 
| Chris Lattner | f52e261 | 2006-01-27 01:44:09 +0000 | [diff] [blame] | 310 |         if (II->getValue()) { | 
 | 311 |           if (Shift) | 
 | 312 |             OS << "|(" << II->getValue() << "<<" << Shift << ")"; | 
 | 313 |           else | 
 | 314 |             OS << "|" << II->getValue(); | 
 | 315 |         } | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 316 |         return; | 
 | 317 |       } | 
 | 318 |  | 
 | 319 |   } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) { | 
| Chris Lattner | f52e261 | 2006-01-27 01:44:09 +0000 | [diff] [blame] | 320 |     if (II->getValue()) { | 
 | 321 |       if (Shift) | 
 | 322 |         OS << "|(" << II->getValue() << "<<" << Shift << ")"; | 
 | 323 |       else | 
 | 324 |         OS << II->getValue(); | 
 | 325 |     } | 
| Chris Lattner | a3ae614 | 2003-08-03 21:57:51 +0000 | [diff] [blame] | 326 |     return; | 
 | 327 |   } | 
 | 328 |  | 
 | 329 |   std::cerr << "Unhandled initializer: " << *Val << "\n"; | 
 | 330 |   throw "In record '" + R->getName() + "' for TSFlag emission."; | 
 | 331 | } | 
| Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 332 |  |