InstrInfoEmitter.cpp revision 65303d6bd777b76735ef179870678a1d14671c54
133ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// The LLVM Compiler Infrastructure 401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// 501d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// This file was developed by the LLVM research group and is distributed under 601d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//===----------------------------------------------------------------------===// 933ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// 1033ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// This tablegen backend is responsible for emitting a description of the target 1133ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// instruction set for the code generator. 1233ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// 1333ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner//===----------------------------------------------------------------------===// 1433ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner 1533ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner#include "InstrInfoEmitter.h" 16803a5f6ecb1823280f80e3c4459aa58627d0484cChris Lattner#include "CodeGenTarget.h" 1733ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner#include "Record.h" 18cb366d980a389e5b9c3fc2b9aae373c0ba2903c6Jeff Cohen#include <algorithm> 192082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm; 20d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 2133ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner// runEnums - Print out enum values for all of the instructions. 2233ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattnervoid InstrInfoEmitter::runEnums(std::ostream &OS) { 23bc01723605de979e67b1aea67385a029f851de34Chris Lattner EmitSourceFileHeader("Target Instruction Enum Values", OS); 242c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner OS << "namespace llvm {\n\n"; 2533ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner 267884b750c33b750177b3f22af75c874c97f728d8Chris Lattner CodeGenTarget Target; 277884b750c33b750177b3f22af75c874c97f728d8Chris Lattner 28a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner // We must emit the PHI opcode first... 297884b750c33b750177b3f22af75c874c97f728d8Chris Lattner Record *InstrInfo = Target.getInstructionSet(); 3033ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner 31ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner std::string Namespace = Target.inst_begin()->second.Namespace; 32ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner 33ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (!Namespace.empty()) 34ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner OS << "namespace " << Namespace << " {\n"; 35ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner OS << " enum {\n"; 36ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner 37d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner std::vector<const CodeGenInstruction*> NumberedInstructions; 38d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner Target.getInstructionsByEnumValue(NumberedInstructions); 39d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner 40d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 41d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner OS << " " << NumberedInstructions[i]->TheDef->getName() 42d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner << ", \t// " << i << "\n"; 43d6488671736d0a5aaee1218748b94d8c68f33716Chris Lattner } 449fdd6e3f50b7fdafff9aa0e1bac0bd2a78d03d71Chris Lattner OS << " INSTRUCTION_LIST_END\n"; 4533ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner OS << " };\n"; 4633ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner if (!Namespace.empty()) 4733ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner OS << "}\n"; 482c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner OS << "} // End llvm namespace \n"; 4933ccf7edff6d784c7f6ea85ada2b67062272073eChris Lattner} 50a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 51a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattnervoid InstrInfoEmitter::printDefList(const std::vector<Record*> &Uses, 52a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner unsigned Num, std::ostream &OS) const { 53a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner OS << "static const unsigned ImplicitList" << Num << "[] = { "; 54a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner for (unsigned i = 0, e = Uses.size(); i != e; ++i) 55a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner OS << getQualifiedName(Uses[i]) << ", "; 56a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner OS << "0 };\n"; 57a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner} 58a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 59d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattnerstatic std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) { 60d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner std::vector<Record*> Result; 61d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner if (Inst.hasVariableNumberOfOperands) 62d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner return Result; // No info for variable operand instrs. 63d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner 64d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) { 6565303d6bd777b76735ef179870678a1d14671c54Chris Lattner if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) { 66d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner Result.push_back(Inst.OperandList[i].Rec); 6765303d6bd777b76735ef179870678a1d14671c54Chris Lattner } else { 68d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner // This might be a multiple operand thing. 6965303d6bd777b76735ef179870678a1d14671c54Chris Lattner // Targets like X86 have registers in their multi-operand operands. 7065303d6bd777b76735ef179870678a1d14671c54Chris Lattner DagInit *MIOI = Inst.OperandList[i].MIOperandInfo; 7165303d6bd777b76735ef179870678a1d14671c54Chris Lattner unsigned NumDefs = MIOI->getNumArgs(); 7265303d6bd777b76735ef179870678a1d14671c54Chris Lattner for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) { 7365303d6bd777b76735ef179870678a1d14671c54Chris Lattner if (NumDefs <= j) { 7465303d6bd777b76735ef179870678a1d14671c54Chris Lattner Result.push_back(0); 7565303d6bd777b76735ef179870678a1d14671c54Chris Lattner } else { 7665303d6bd777b76735ef179870678a1d14671c54Chris Lattner DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j)); 7765303d6bd777b76735ef179870678a1d14671c54Chris Lattner Result.push_back(Def ? Def->getDef() : 0); 7865303d6bd777b76735ef179870678a1d14671c54Chris Lattner } 7965303d6bd777b76735ef179870678a1d14671c54Chris Lattner } 80d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner } 81d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner } 82d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner return Result; 83d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner} 84d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner 85a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 86a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner// run - Emit the main instruction description records for the target... 87a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattnervoid InstrInfoEmitter::run(std::ostream &OS) { 88b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey GatherItinClasses(); 89b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 90bc01723605de979e67b1aea67385a029f851de34Chris Lattner EmitSourceFileHeader("Target Instruction Descriptors", OS); 912c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner OS << "namespace llvm {\n\n"; 922c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner 937884b750c33b750177b3f22af75c874c97f728d8Chris Lattner CodeGenTarget Target; 947884b750c33b750177b3f22af75c874c97f728d8Chris Lattner const std::string &TargetName = Target.getName(); 957884b750c33b750177b3f22af75c874c97f728d8Chris Lattner Record *InstrInfo = Target.getInstructionSet(); 96a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner Record *PHI = InstrInfo->getValueAsDef("PHIInst"); 97a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 9873ff5120eb8b8c0ccbfed8a17f1024c67a75f319Alkis Evlogimenos // Emit empty implicit uses and defs lists 99a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner OS << "static const unsigned EmptyImpList[] = { 0 };\n"; 100a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner 101a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner // Keep track of all of the def lists we have emitted already. 102a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner std::map<std::vector<Record*>, unsigned> EmittedLists; 103a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner unsigned ListNumber = 0; 104a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner 105a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner // Emit all of the instruction's implicit uses and defs. 106ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 107ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner E = Target.inst_end(); II != E; ++II) { 108ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner Record *Inst = II->second.TheDef; 109366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner std::vector<Record*> Uses = Inst->getValueAsListOfDefs("Uses"); 110366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner if (!Uses.empty()) { 111a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner unsigned &IL = EmittedLists[Uses]; 112a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner if (!IL) printDefList(Uses, IL = ++ListNumber, OS); 113a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner } 114366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); 115366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner if (!Defs.empty()) { 116366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner unsigned &IL = EmittedLists[Defs]; 117366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner if (!IL) printDefList(Defs, IL = ++ListNumber, OS); 118a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner } 119a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner } 120a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 121d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner std::map<std::vector<Record*>, unsigned> OperandInfosEmitted; 122d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner unsigned OperandListNum = 0; 123d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OperandInfosEmitted[std::vector<Record*>()] = ++OperandListNum; 124d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner 1250e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner // Emit all of the operand info records. 1260e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner OS << "\n"; 1270e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 1280e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner E = Target.inst_end(); II != E; ++II) { 129d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner std::vector<Record*> OperandInfo = GetOperandInfo(II->second); 130d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner unsigned &N = OperandInfosEmitted[OperandInfo]; 131d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner if (N == 0) { 132d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner N = ++OperandListNum; 133d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { "; 134d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) { 13565303d6bd777b76735ef179870678a1d14671c54Chris Lattner Record *RC = OperandInfo[i]; 13665303d6bd777b76735ef179870678a1d14671c54Chris Lattner // FIXME: We only care about register operands for now. 13765303d6bd777b76735ef179870678a1d14671c54Chris Lattner if (RC && RC->isSubClassOf("RegisterClass")) { 1388d30c23d2638bdc9a3e4fc7ba764adf5df043ee5Chris Lattner OS << "{ &" << getQualifiedName(RC) << "RegClass }, "; 139d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner } else { 140d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OS << "{ 0 }, "; 141d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner } 142d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner } 1430e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner OS << "};\n"; 1440e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner } 1450e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner } 1460e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner 1470e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner // Emit all of the TargetInstrDescriptor records. 1480e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner // 149a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner OS << "\nstatic const TargetInstrDescriptor " << TargetName 150a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner << "Insts[] = {\n"; 151366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner emitRecord(Target.getPHIInstruction(), 0, InstrInfo, EmittedLists, 152d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OperandInfosEmitted, OS); 153a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 154ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner unsigned i = 0; 155ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner for (CodeGenTarget::inst_iterator II = Target.inst_begin(), 156ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner E = Target.inst_end(); II != E; ++II) 157ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (II->second.TheDef != PHI) 158366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner emitRecord(II->second, ++i, InstrInfo, EmittedLists, 159d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OperandInfosEmitted, OS); 160a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner OS << "};\n"; 1612c38413b3f5420f45f2f8220b21862246d446dd0Chris Lattner OS << "} // End llvm namespace \n"; 162a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner} 163a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 164ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattnervoid InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, 165a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner Record *InstrInfo, 166366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner std::map<std::vector<Record*>, unsigned> &EmittedLists, 167d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner std::map<std::vector<Record*>, unsigned> &OpInfo, 168a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner std::ostream &OS) { 169d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner int NumOperands; 170d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner if (Inst.hasVariableNumberOfOperands) 171d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner NumOperands = -1; 172d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner else if (!Inst.OperandList.empty()) 173d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner // Each logical operand can be multiple MI operands. 174d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner NumOperands = Inst.OperandList.back().MIOperandNo + 175d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner Inst.OperandList.back().MINumOperands; 176d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner else 177d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner NumOperands = 0; 178d98958f4bdd5a41b1d30668c25fe259069a04f92Chris Lattner 1792d12b2cf7513e7ee855deec0de293311d676cb75Chris Lattner OS << " { \""; 1802d12b2cf7513e7ee855deec0de293311d676cb75Chris Lattner if (Inst.Name.empty()) 1812d12b2cf7513e7ee855deec0de293311d676cb75Chris Lattner OS << Inst.TheDef->getName(); 1822d12b2cf7513e7ee855deec0de293311d676cb75Chris Lattner else 1832d12b2cf7513e7ee855deec0de293311d676cb75Chris Lattner OS << Inst.Name; 184b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 185b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey unsigned ItinClass = !IsItineraries ? 0 : 186b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey ItinClassNumber(Inst.TheDef->getValueAsDef("Itinerary")->getName()); 187b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 188b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey OS << "\",\t" << NumOperands << ", -1, 0, false, 0, 0, " 189b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey << ItinClass 190b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey << ", 0"; 191a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 192a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner // Emit all of the target indepedent flags... 193ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (Inst.isReturn) OS << "|M_RET_FLAG"; 194ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (Inst.isBranch) OS << "|M_BRANCH_FLAG"; 195ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (Inst.isBarrier) OS << "|M_BARRIER_FLAG"; 1965b71d3af35f941585acb50de4909cff20f68680dChris Lattner if (Inst.hasDelaySlot) OS << "|M_DELAY_SLOT_FLAG"; 197ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (Inst.isCall) OS << "|M_CALL_FLAG"; 198cdd66b524f62ef6acd6bfa4e586edf8a406c4928Nate Begeman if (Inst.isLoad) OS << "|M_LOAD_FLAG"; 199cdd66b524f62ef6acd6bfa4e586edf8a406c4928Nate Begeman if (Inst.isStore) OS << "|M_STORE_FLAG"; 200ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (Inst.isTwoAddress) OS << "|M_2_ADDR_FLAG"; 201aad75aa1a235ec1ab121ec2a9c745577493ed323Chris Lattner if (Inst.isConvertibleToThreeAddress) OS << "|M_CONVERTIBLE_TO_3_ADDR"; 202aad75aa1a235ec1ab121ec2a9c745577493ed323Chris Lattner if (Inst.isCommutable) OS << "|M_COMMUTABLE"; 203ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner if (Inst.isTerminator) OS << "|M_TERMINATOR_FLAG"; 2045f89bf0f9df54687f4474fe13f5d1a8635d85d5aChris Lattner if (Inst.usesCustomDAGSchedInserter) 2058b50f9b8dcd6da00ddc961ecda967719eb745deeChris Lattner OS << "|M_USES_CUSTOM_DAG_SCHED_INSERTION"; 206a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner OS << ", 0"; 207a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 208a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner // Emit all of the target-specific flags... 209a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner ListInit *LI = InstrInfo->getValueAsListInit("TSFlagsFields"); 210a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); 211a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (LI->getSize() != Shift->getSize()) 212a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner throw "Lengths of " + InstrInfo->getName() + 213a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner ":(TargetInfoFields, TargetInfoPositions) must be equal!"; 214a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 215a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner for (unsigned i = 0, e = LI->getSize(); i != e; ++i) 216ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)), 217a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner dynamic_cast<IntInit*>(Shift->getElement(i)), OS); 218a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 219a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner OS << ", "; 220a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 221a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner // Emit the implicit uses and defs lists... 222366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); 223366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner if (UseList.empty()) 224a3ac88d8ab4605f6c1c298a8cdaa89d16c3756b4Chris Lattner OS << "EmptyImpList, "; 2253da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman else 226366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner OS << "ImplicitList" << EmittedLists[UseList] << ", "; 227a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 228366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); 229366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner if (DefList.empty()) 2300e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner OS << "EmptyImpList, "; 2313da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman else 232366080c5e6b4b8e1f07829a2489cc5d21f51bf3bChris Lattner OS << "ImplicitList" << EmittedLists[DefList] << ", "; 233a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 2340e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner // Emit the operand info. 235d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner std::vector<Record*> OperandInfo = GetOperandInfo(Inst); 236d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner if (OperandInfo.empty()) 237d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OS << "0"; 2380e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner else 239d5aa3e26bb02732fddadecfd66112352a74742a0Chris Lattner OS << "OperandInfo" << OpInfo[OperandInfo]; 2400e384b66a781fc0ff005f475a7ab151afa054fb0Chris Lattner 241ec3524064c57fbc2c5976ca301bbaadc94006d07Chris Lattner OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; 242a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner} 243a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 244b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskeystruct LessRecord { 245b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey bool operator()(const Record *Rec1, const Record *Rec2) const { 246b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey return Rec1->getName() < Rec2->getName(); 247b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey } 248b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey}; 249b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskeyvoid InstrInfoEmitter::GatherItinClasses() { 250b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey std::vector<Record*> DefList = 251b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey Records.getAllDerivedDefinitions("InstrItinClass"); 252b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey IsItineraries = !DefList.empty(); 253b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 254b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey if (!IsItineraries) return; 255b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 256b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey sort(DefList.begin(), DefList.end(), LessRecord()); 257b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 258b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey for (unsigned i = 0, N = DefList.size(); i < N; i++) { 259b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey Record *Def = DefList[i]; 2606cee630070b1a7183ed56a8404e812629f5ca538Jim Laskey ItinClassMap[Def->getName()] = i; 261b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey } 262b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey} 263b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 264b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskeyunsigned InstrInfoEmitter::ItinClassNumber(std::string ItinName) { 265b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey return ItinClassMap[ItinName]; 266b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey} 267b5a0c0ee059db5994d4fec7ebd03c048b4fcd308Jim Laskey 268a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattnervoid InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val, 269a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner IntInit *ShiftInt, std::ostream &OS) { 270a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (Val == 0 || ShiftInt == 0) 271a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner throw std::string("Illegal value or shift amount in TargetInfo*!"); 272a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner RecordVal *RV = R->getValue(Val->getValue()); 273a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner int Shift = ShiftInt->getValue(); 274a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 275a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (RV == 0 || RV->getValue() == 0) 276a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner throw R->getName() + " doesn't have a field named '" + Val->getValue()+"'!"; 277a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 278a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner Init *Value = RV->getValue(); 279a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (BitInit *BI = dynamic_cast<BitInit*>(Value)) { 280a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (BI->getValue()) OS << "|(1<<" << Shift << ")"; 281a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner return; 282a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) { 283a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner // Convert the Bits to an integer to print... 284a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner Init *I = BI->convertInitializerTo(new IntRecTy()); 285a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (I) 286a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (IntInit *II = dynamic_cast<IntInit*>(I)) { 287a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (II->getValue()) 288a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner OS << "|(" << II->getValue() << "<<" << Shift << ")"; 289a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner return; 290a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner } 291a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 292a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) { 293a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner if (II->getValue()) OS << "|(" << II->getValue() << "<<" << Shift << ")"; 294a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner return; 295a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner } 296a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner 297a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner std::cerr << "Unhandled initializer: " << *Val << "\n"; 298a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner throw "In record '" + R->getName() + "' for TSFlag emission."; 299a3ae6143c1ec9c39a7beb07960f89edd4736b018Chris Lattner} 300d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 301