12e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 32e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// The LLVM Compiler Infrastructure 42e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 53060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// This file is distributed under the University of Illinois Open Source 63060910e290949a9ac5eda8726d030790c4d60ffChris Lattner// License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 82e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===----------------------------------------------------------------------===// 92e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 102e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// This tablegen backend is emits an assembly printer for the current target. 112e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// Note that this is currently fairly skeletal, but will grow over time. 122e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// 132e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===----------------------------------------------------------------------===// 142e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 15d32c02f3145c8d5114c9bd367e9ff15f4aed2e15Sean Callanan#include "AsmWriterInst.h" 162e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "CodeGenTarget.h" 17c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen#include "SequenceToOffsetTable.h" 18f553587a4f5bdd9226c6f29bb46a32b6f67986ffCraig Topper#include "llvm/ADT/StringExtras.h" 19bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson#include "llvm/ADT/Twine.h" 20bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/Debug.h" 21bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/MathExtras.h" 227c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Error.h" 237c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h" 246f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 25615ed993e115f8bc97ff0678aa861629fec93880Jeff Cohen#include <algorithm> 266f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <cassert> 276f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <map> 286f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen#include <vector> 292e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnerusing namespace llvm; 302e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 316f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace { 326f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenclass AsmWriterEmitter { 336f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen RecordKeeper &Records; 346f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap; 356f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<const CodeGenInstruction*> NumberedInstructions; 366f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenpublic: 376f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen AsmWriterEmitter(RecordKeeper &R) : Records(R) {} 386f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 396f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void run(raw_ostream &o); 406f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 416f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenprivate: 426f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitPrintInstruction(raw_ostream &o); 436f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitGetRegisterName(raw_ostream &o); 446f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void EmitPrintAliasInstruction(raw_ostream &O); 456f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 466f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen AsmWriterInst *getAsmWriterInstByID(unsigned ID) const { 476f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen assert(ID < NumberedInstructions.size()); 486f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I = 496f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen CGIAWIMap.find(NumberedInstructions[ID]); 506f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen assert(I != CGIAWIMap.end() && "Didn't find inst!"); 516f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen return I->second; 526f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen } 536f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen void FindUniqueOperandCommands(std::vector<std::string> &UOC, 546f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<unsigned> &InstIdxs, 556f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen std::vector<unsigned> &InstOpsUsed) const; 566f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen}; 576f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // end anonymous namespace 586f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 5938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattnerstatic void PrintCases(std::vector<std::pair<std::string, 601a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar AsmWriterOperand> > &OpsToPrint, raw_ostream &O) { 6138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << " case " << OpsToPrint.back().first << ": "; 6238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterOperand TheOp = OpsToPrint.back().second; 6338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.pop_back(); 6438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 6538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Check to see if any other operands are identical in this list, and if so, 6638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // emit a case label for them. 6738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner for (unsigned i = OpsToPrint.size(); i != 0; --i) 6838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner if (OpsToPrint[i-1].second == TheOp) { 6938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "\n case " << OpsToPrint[i-1].first << ": "; 7038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.erase(OpsToPrint.begin()+i-1); 7138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner } 7238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 7338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Finally, emit the code. 74bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << TheOp.getCode(); 7538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "break;\n"; 7638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner} 7738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 78870c016934bacf43995d89531b166ae095ee3675Chris Lattner 79870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// EmitInstructions - Emit the last instruction in the vector and any other 80870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// instructions that are suitably similar to it. 81870c016934bacf43995d89531b166ae095ee3675Chris Lattnerstatic void EmitInstructions(std::vector<AsmWriterInst> &Insts, 821a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &O) { 83870c016934bacf43995d89531b166ae095ee3675Chris Lattner AsmWriterInst FirstInst = Insts.back(); 84870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.pop_back(); 85870c016934bacf43995d89531b166ae095ee3675Chris Lattner 86870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::vector<AsmWriterInst> SimilarInsts; 87870c016934bacf43995d89531b166ae095ee3675Chris Lattner unsigned DifferingOperand = ~0; 88870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = Insts.size(); i != 0; --i) { 89f876668518097413a904537ce9d249953987508cChris Lattner unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst); 90f876668518097413a904537ce9d249953987508cChris Lattner if (DiffOp != ~1U) { 91870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (DifferingOperand == ~0U) // First match! 92870c016934bacf43995d89531b166ae095ee3675Chris Lattner DifferingOperand = DiffOp; 93870c016934bacf43995d89531b166ae095ee3675Chris Lattner 94870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this differs in the same operand as the rest of the instructions in 95870c016934bacf43995d89531b166ae095ee3675Chris Lattner // this class, move it to the SimilarInsts list. 96f876668518097413a904537ce9d249953987508cChris Lattner if (DifferingOperand == DiffOp || DiffOp == ~0U) { 97870c016934bacf43995d89531b166ae095ee3675Chris Lattner SimilarInsts.push_back(Insts[i-1]); 98870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.erase(Insts.begin()+i-1); 99870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 100870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 101870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 102870c016934bacf43995d89531b166ae095ee3675Chris Lattner 103a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << FirstInst.CGI->Namespace << "::" 104870c016934bacf43995d89531b166ae095ee3675Chris Lattner << FirstInst.CGI->TheDef->getName() << ":\n"; 105870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i) 106a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << SimilarInsts[i].CGI->Namespace << "::" 107870c016934bacf43995d89531b166ae095ee3675Chris Lattner << SimilarInsts[i].CGI->TheDef->getName() << ":\n"; 108870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) { 109870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (i != DifferingOperand) { 110870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If the operand is the same for all instructions, just print it. 111bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << " " << FirstInst.Operands[i].getCode(); 112870c016934bacf43995d89531b166ae095ee3675Chris Lattner } else { 113870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this is the operand that varies between all of the instructions, 114870c016934bacf43995d89531b166ae095ee3675Chris Lattner // emit a switch for just this operand now. 115870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " switch (MI->getOpcode()) {\n"; 11638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint; 117a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" + 11838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.CGI->TheDef->getName(), 11938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.Operands[i])); 1203da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 121870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { 12238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterInst &AWI = SimilarInsts[si]; 123a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+ 12438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.CGI->TheDef->getName(), 12538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.Operands[i])); 126870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 12738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::reverse(OpsToPrint.begin(), OpsToPrint.end()); 12838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner while (!OpsToPrint.empty()) 12938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner PrintCases(OpsToPrint, O); 130870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " }"; 131870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 132870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << "\n"; 133870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 134870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " break;\n"; 135870c016934bacf43995d89531b166ae095ee3675Chris Lattner} 136b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 137bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattnervoid AsmWriterEmitter:: 1389255b8d349768a02b2d139a43984c9b544098122Jim GrosbachFindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 13996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstIdxs, 14096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstOpsUsed) const { 141195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner InstIdxs.assign(NumberedInstructions.size(), ~0U); 1429255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 143bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // This vector parallels UniqueOperandCommands, keeping track of which 144bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // instructions each case are used for. It is a comma separated string of 145bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // enums. 146bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> InstrsForCase; 147bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.resize(UniqueOperandCommands.size()); 14896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.assign(UniqueOperandCommands.size(), 0); 1499255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 150bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 151bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner const AsmWriterInst *Inst = getAsmWriterInstByID(i); 152b9449d663921fc27d503d048028937c5a19b6f8bBill Wendling if (Inst == 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc. 1539255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 154bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Command; 155b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst->Operands.empty()) 156bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner continue; // Instruction already done. 157191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 158b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner Command = " " + Inst->Operands[0].getCode() + "\n"; 159191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 160bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Check to see if we already have 'Command' in UniqueOperandCommands. 161bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If not, add it. 162bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner bool FoundIt = false; 163bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx) 164bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands[idx] == Command) { 165bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = idx; 166bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += ", "; 167bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += Inst->CGI->TheDef->getName(); 168bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner FoundIt = true; 169bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 170bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 171bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!FoundIt) { 172bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = UniqueOperandCommands.size(); 173bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands.push_back(Command); 174bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.push_back(Inst->CGI->TheDef->getName()); 17596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 17696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // This command matches one operand so far. 17796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.push_back(1); 17896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 17996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 1809255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 18196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // For each entry of UniqueOperandCommands, there is a set of instructions 18296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // that uses it. If the next command of all instructions in the set are 18396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // identical, fold it into the command. 18496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size(); 18596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner CommandIdx != e; ++CommandIdx) { 1869255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 18796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned Op = 1; ; ++Op) { 18896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Scan for the first instruction in the set. 18996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned>::iterator NIT = 19096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx); 19196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (NIT == InstIdxs.end()) break; // No commonality. 19296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 19396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // If this instruction has no more operands, we isn't anything to merge 19496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // into this command. 1959255b8d349768a02b2d139a43984c9b544098122Jim Grosbach const AsmWriterInst *FirstInst = 19696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 19796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!FirstInst || FirstInst->Operands.size() == Op) 19896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 19996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 20096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Otherwise, scan to see if all of the other instructions in this command 20196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // set share the operand. 20296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner bool AllSame = true; 203c8d060503619d32012167d2427891a85e116f3d2David Greene // Keep track of the maximum, number of operands or any 204c8d060503619d32012167d2427891a85e116f3d2David Greene // instruction we see in the group. 205c8d060503619d32012167d2427891a85e116f3d2David Greene size_t MaxSize = FirstInst->Operands.size(); 206c8d060503619d32012167d2427891a85e116f3d2David Greene 20796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx); 20896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT != InstIdxs.end(); 20996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) { 21096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, found another instruction in this command set. If the operand 21196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // matches, we're ok, otherwise bail out. 2129255b8d349768a02b2d139a43984c9b544098122Jim Grosbach const AsmWriterInst *OtherInst = 21396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 214c8d060503619d32012167d2427891a85e116f3d2David Greene 215c8d060503619d32012167d2427891a85e116f3d2David Greene if (OtherInst && 216c8d060503619d32012167d2427891a85e116f3d2David Greene OtherInst->Operands.size() > FirstInst->Operands.size()) 217c8d060503619d32012167d2427891a85e116f3d2David Greene MaxSize = std::max(MaxSize, OtherInst->Operands.size()); 218c8d060503619d32012167d2427891a85e116f3d2David Greene 21996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!OtherInst || OtherInst->Operands.size() == Op || 22096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner OtherInst->Operands[Op] != FirstInst->Operands[Op]) { 22196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner AllSame = false; 22296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 22396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 22496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 22596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!AllSame) break; 2269255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 22796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, everything in this command set has the same next operand. Add it 22896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // to UniqueOperandCommands and remember that it was consumed. 22996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n"; 2309255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 23196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner UniqueOperandCommands[CommandIdx] += Command; 23296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed[CommandIdx]++; 233bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 234bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 2359255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 236bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Prepend some of the instructions each case is used for onto the case val. 237bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) { 238bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Instrs = InstrsForCase[i]; 239bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (Instrs.size() > 70) { 240bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs.erase(Instrs.begin()+70, Instrs.end()); 241bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs += "..."; 242bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 2439255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 244bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!Instrs.empty()) 2459255b8d349768a02b2d139a43984c9b544098122Jim Grosbach UniqueOperandCommands[i] = " // " + Instrs + "\n" + 246bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands[i]; 247bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 248bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner} 249bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 250bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 2519bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbarstatic void UnescapeString(std::string &Str) { 2529bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar for (unsigned i = 0; i != Str.size(); ++i) { 2539bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar if (Str[i] == '\\' && i != Str.size()-1) { 2549bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar switch (Str[i+1]) { 2559bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar default: continue; // Don't execute the code after the switch. 2569bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'a': Str[i] = '\a'; break; 2579bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'b': Str[i] = '\b'; break; 2589bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'e': Str[i] = 27; break; 2599bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'f': Str[i] = '\f'; break; 2609bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'n': Str[i] = '\n'; break; 2619bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'r': Str[i] = '\r'; break; 2629bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 't': Str[i] = '\t'; break; 2639bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'v': Str[i] = '\v'; break; 2649bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '"': Str[i] = '\"'; break; 2659bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '\'': Str[i] = '\''; break; 2669bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '\\': Str[i] = '\\'; break; 2679bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2689bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar // Nuke the second character. 2699bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar Str.erase(Str.begin()+i+1); 2709bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2719bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2729bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar} 2739bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar 27405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner/// EmitPrintInstruction - Generate the code for the "printInstruction" method 27505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner/// implementation. 27605af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 27767db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 278175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner Record *AsmWriter = Target.getAsmWriter(); 279953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 280ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter"); 281ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr"; 2829255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2832e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << 2842e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// printInstruction - This method is automatically generated by tablegen\n" 28505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// from the instruction set description.\n" 28641aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner "void " << Target.getName() << ClassName 287ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach << "::printInstruction(const " << MachineInstrClassName 288ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach << " *MI, raw_ostream &O) {\n"; 2892e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 2905765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner std::vector<AsmWriterInst> Instructions; 2915765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 2922e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 2932e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner E = Target.inst_end(); I != E; ++I) 2946a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner if (!(*I)->AsmString.empty() && 2956a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner (*I)->TheDef->getName() != "PHI") 296d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan Instructions.push_back( 2979255b8d349768a02b2d139a43984c9b544098122Jim Grosbach AsmWriterInst(**I, 298d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("Variant"), 299d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("FirstOperandColumn"), 300d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("OperandSpacing"))); 3015765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 302bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Get the instruction numbering. 303f65027842e82027dd6e8020586a299aaa548e355Chris Lattner NumberedInstructions = Target.getInstructionsByEnumValue(); 3049255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3056af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not 3066af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // all machine instructions are necessarily being printed, so there may be 3076af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // target instructions not in this map. 3086af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) 3096af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); 3106af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 3116af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Build an aggregate string, and build a table of offsets into it. 31294338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer SequenceToOffsetTable<std::string> StringTable; 3139255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 314259bda48e2c6b886f707513781f1b76595d4ad0dChris Lattner /// OpcodeInfo - This encodes the index of the string to use for the first 3155561640043666174a1e4d828107702a8992e59f6Chris Lattner /// chunk of the output as well as indices used for operand printing. 3165561640043666174a1e4d828107702a8992e59f6Chris Lattner std::vector<unsigned> OpcodeInfo; 3179255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 31894338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer // Add all strings to the string table upfront so it can generate an optimized 31994338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer // representation. 32094338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 32194338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 32294338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer if (AWI != 0 && 323016c679c50e13532a30d80b59232e4b82ab807bfJim Grosbach AWI->Operands[0].OperandType == 324016c679c50e13532a30d80b59232e4b82ab807bfJim Grosbach AsmWriterOperand::isLiteralTextOperand && 32594338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer !AWI->Operands[0].Str.empty()) { 32694338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer std::string Str = AWI->Operands[0].Str; 32794338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer UnescapeString(Str); 32894338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer StringTable.add(Str); 32994338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer } 33094338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer } 33194338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer 33294338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer StringTable.layout(); 33394338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer 3345561640043666174a1e4d828107702a8992e59f6Chris Lattner unsigned MaxStringIdx = 0; 3356af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 3366af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 3376af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner unsigned Idx; 338a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner if (AWI == 0) { 3396af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Something not handled by the asmwriter printer. 3403200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = ~0U; 3419255b8d349768a02b2d139a43984c9b544098122Jim Grosbach } else if (AWI->Operands[0].OperandType != 342a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AsmWriterOperand::isLiteralTextOperand || 343a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AWI->Operands[0].Str.empty()) { 344a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner // Something handled by the asmwriter printer, but with no leading string. 34594338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer Idx = StringTable.get(""); 3466af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } else { 3473200fc9badda8964fac571995bd74a3954977ddcChris Lattner std::string Str = AWI->Operands[0].Str; 3483200fc9badda8964fac571995bd74a3954977ddcChris Lattner UnescapeString(Str); 34994338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer Idx = StringTable.get(Str); 3503200fc9badda8964fac571995bd74a3954977ddcChris Lattner MaxStringIdx = std::max(MaxStringIdx, Idx); 3519255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3526af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Nuke the string from the operand list. It is now handled! 3536af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AWI->Operands.erase(AWI->Operands.begin()); 3546af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 3559255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3563200fc9badda8964fac571995bd74a3954977ddcChris Lattner // Bias offset by one since we want 0 as a sentinel. 3573200fc9badda8964fac571995bd74a3954977ddcChris Lattner OpcodeInfo.push_back(Idx+1); 358bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3599255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3605561640043666174a1e4d828107702a8992e59f6Chris Lattner // Figure out how many bits we used for the string index. 3613200fc9badda8964fac571995bd74a3954977ddcChris Lattner unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2); 3629255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 363bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // To reduce code size, we compactify common instructions into a few bits 364bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // in the opcode-indexed table. 365b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner unsigned BitsLeft = 32-AsmStrBits; 366bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 367bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::vector<std::string> > TableDrivenOperandPrinters; 3689255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 369b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner while (1) { 370bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> UniqueOperandCommands; 371bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<unsigned> InstIdxs; 37296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> NumInstOpsHandled; 37396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs, 37496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NumInstOpsHandled); 3759255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 376bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we ran out of operands to print, we're done. 377bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands.empty()) break; 3789255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 379bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 380bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 381bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size()); 3829255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 383bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we don't have enough bits for this operand, don't include it. 384bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (NumBits > BitsLeft) { 385569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner DEBUG(errs() << "Not enough bits to densely encode " << NumBits 386569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner << " more bits\n"); 387bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 388bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3899255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 390bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Otherwise, we can include this in the initial lookup table. Add it in. 391bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 392bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i) 393195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner if (InstIdxs[i] != ~0U) 394195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits); 3959255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 396b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remove the info about this operand. 397b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 398b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (AsmWriterInst *Inst = getAsmWriterInstByID(i)) 39996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!Inst->Operands.empty()) { 40096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner unsigned NumOps = NumInstOpsHandled[InstIdxs[i]]; 4010a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner assert(NumOps <= Inst->Operands.size() && 4020a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner "Can't remove this many ops!"); 40396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.erase(Inst->Operands.begin(), 40496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.begin()+NumOps); 40596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 406b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner } 4079255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 408b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remember the handlers for this set of operands. 409bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner TableDrivenOperandPrinters.push_back(UniqueOperandCommands); 410bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 4119255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4129255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4139255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4145561640043666174a1e4d828107702a8992e59f6Chris Lattner O<<" static const unsigned OpInfo[] = {\n"; 415bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 416b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " " << OpcodeInfo[i] << "U,\t// " 4175561640043666174a1e4d828107702a8992e59f6Chris Lattner << NumberedInstructions[i]->TheDef->getName() << "\n"; 4186af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 419bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Add a dummy entry so the array init doesn't end with a comma. 4205561640043666174a1e4d828107702a8992e59f6Chris Lattner O << " 0U\n"; 4216af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " };\n\n"; 4229255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4236af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Emit the string itself. 42494338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer O << " const char AsmStrs[] = {\n"; 42594338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer StringTable.emit(O, printChar); 42694338594efed5575ab83b7d8d4bacb0dbf1778a3Benjamin Kramer O << " };\n\n"; 4276af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 4284eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng O << " O << \"\\t\";\n\n"; 4294eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng 4306af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " // Emit the opcode for the instruction.\n" 4315561640043666174a1e4d828107702a8992e59f6Chris Lattner << " unsigned Bits = OpInfo[MI->getOpcode()];\n" 43241aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" 4333200fc9badda8964fac571995bd74a3954977ddcChris Lattner << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; 434a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 435bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Output the table driven operand information. 436b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner BitsLeft = 32-AsmStrBits; 437bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) { 438bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> &Commands = TableDrivenOperandPrinters[i]; 439f876668518097413a904537ce9d249953987508cChris Lattner 440bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 441bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 442bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(Commands.size()); 443bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner assert(NumBits <= BitsLeft && "consistency error"); 4449255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 445bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Emit code to extract this field from Bits. 446bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 4479255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 448bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << "\n // Fragment " << i << " encoded into " << NumBits 449e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " bits for " << Commands.size() << " unique commands.\n"; 4509255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 45196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (Commands.size() == 2) { 452e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Emit two possibilitys with if/else. 453e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 454e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 455e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[1] 456e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " } else {\n" 457e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[0] 458e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " }\n\n"; 459168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher } else if (Commands.size() == 1) { 460168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher // Emit a single possibility. 461168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher O << Commands[0] << "\n\n"; 462e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } else { 463e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 464e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 465e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " default: // unreachable.\n"; 4669255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 467e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Print out all the cases. 468e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner for (unsigned i = 0, e = Commands.size(); i != e; ++i) { 469e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " case " << i << ":\n"; 470e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << Commands[i]; 471e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " break;\n"; 472e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } 473e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " }\n\n"; 474bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 475bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 4769255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 477b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Okay, delete instructions with no operand info left. 478bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { 479bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Entire instruction has been emitted? 480bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner AsmWriterInst &Inst = Instructions[i]; 481b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst.Operands.empty()) { 482bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instructions.erase(Instructions.begin()+i); 483b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner --i; --e; 484bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 485bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 486bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 4879255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 488bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Because this is a vector, we want to emit from the end. Reverse all of the 489870c016934bacf43995d89531b166ae095ee3675Chris Lattner // elements in the vector. 490870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::reverse(Instructions.begin(), Instructions.end()); 4919255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4929255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 493700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // Now that we've emitted all of the operand info that fit into 32 bits, emit 494700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // information for those instructions that are left. This is a less dense 495700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // encoding, but we expect the main 32-bit table to handle the majority of 496700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // instructions. 497b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner if (!Instructions.empty()) { 498b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner // Find the opcode # of inline asm. 499b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " switch (MI->getOpcode()) {\n"; 500b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner while (!Instructions.empty()) 501b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner EmitInstructions(Instructions, O); 502870c016934bacf43995d89531b166ae095ee3675Chris Lattner 503b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " }\n"; 50441aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner O << " return;\n"; 505b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner } 506c8d060503619d32012167d2427891a85e116f3d2David Greene 5070a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner O << "}\n"; 5082e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner} 50905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 510bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Andersonstatic void 511bea6f615eefae279e53bbb63a31d2c3c67274c45Owen AndersonemitRegisterNameString(raw_ostream &O, StringRef AltName, 5129b1b25f0631b22cd09c2fa7383ce28721fa3e212Craig Topper const std::vector<CodeGenRegister*> &Registers) { 513c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen SequenceToOffsetTable<std::string> StringTable; 514c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen SmallVector<std::string, 4> AsmNames(Registers.size()); 515bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 516bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson const CodeGenRegister &Reg = *Registers[i]; 517c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen std::string &AsmName = AsmNames[i]; 518bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 519bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // "NoRegAltName" is special. We don't need to do a lookup for that, 520bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // as it's just a reference to the default register name. 521bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (AltName == "" || AltName == "NoRegAltName") { 522bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson AsmName = Reg.TheDef->getValueAsString("AsmName"); 523bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (AsmName.empty()) 524bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson AsmName = Reg.getName(); 525bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } else { 526bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // Make sure the register has an alternate name for this index. 527bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson std::vector<Record*> AltNameList = 528bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Reg.TheDef->getValueAsListOfDefs("RegAltNameIndices"); 529bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson unsigned Idx = 0, e; 530bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson for (e = AltNameList.size(); 531bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Idx < e && (AltNameList[Idx]->getName() != AltName); 532bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson ++Idx) 533bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson ; 534bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // If the register has an alternate name for this index, use it. 535bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson // Otherwise, leave it empty as an error flag. 536bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (Idx < e) { 537bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson std::vector<std::string> AltNames = 538bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Reg.TheDef->getValueAsListOfStrings("AltNames"); 539bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (AltNames.size() <= Idx) 540bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson throw TGError(Reg.TheDef->getLoc(), 541bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson (Twine("Register definition missing alt name for '") + 542bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson AltName + "'.").str()); 543bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson AsmName = AltNames[Idx]; 544bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 545bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 546c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen StringTable.add(AsmName); 547c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen } 548c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen 549c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen StringTable.layout(); 550c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen O << " static const char AsmStrs" << AltName << "[] = {\n"; 551c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen StringTable.emit(O, printChar); 552c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen O << " };\n\n"; 553bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 554a4bd58b0f0d6ca33ff230aff450c9f2b94934bffCraig Topper O << " static const unsigned RegAsmOffset" << AltName << "[] = {"; 555c19f72bd83e8cb2cc31257008ee9d7797dbf3dbbJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 556a4bd58b0f0d6ca33ff230aff450c9f2b94934bffCraig Topper if ((i % 14) == 0) 557a4bd58b0f0d6ca33ff230aff450c9f2b94934bffCraig Topper O << "\n "; 558a4bd58b0f0d6ca33ff230aff450c9f2b94934bffCraig Topper O << StringTable.get(AsmNames[i]) << ", "; 559bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 5609b1b25f0631b22cd09c2fa7383ce28721fa3e212Craig Topper O << "\n };\n" 561bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << "\n"; 562bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson} 56305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 56405af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 56567db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 56605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner Record *AsmWriter = Target.getAsmWriter(); 56705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 568abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const std::vector<CodeGenRegister*> &Registers = 569abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Target.getRegBank().getRegisters(); 570bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices(); 571bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson bool hasAltNames = AltNameIndices.size() > 1; 5729255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 57305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner O << 57405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" 57505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// from the register set description. This returns the assembler name\n" 57605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// for the specified register.\n" 577bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson "const char *" << Target.getName() << ClassName << "::"; 578bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (hasAltNames) 579bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; 580bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson else 581bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson O << "getRegisterName(unsigned RegNo) {\n"; 582bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson O << " assert(RegNo && RegNo < " << (Registers.size()+1) 583bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " && \"Invalid register number!\");\n" 584f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner << "\n"; 5859255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 586bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (hasAltNames) { 587bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) 588bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson emitRegisterNameString(O, AltNameIndices[i]->getName(), Registers); 589bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } else 590bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson emitRegisterNameString(O, "", Registers); 591bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 592bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (hasAltNames) { 593d66b9a222b38d7d29646c582b70a1c107ca615deJakob Stoklund Olesen O << " const unsigned *RegAsmOffset;\n" 594bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " const char *AsmStrs;\n" 595bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " switch(AltIdx) {\n" 596655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper << " default: llvm_unreachable(\"Invalid register alt name index!\");\n"; 597bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) { 598bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace"); 599bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson StringRef AltName(AltNameIndices[i]->getName()); 600bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson O << " case " << Namespace << "::" << AltName 601bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << ":\n" 602bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " AsmStrs = AsmStrs" << AltName << ";\n" 603bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " RegAsmOffset = RegAsmOffset" << AltName << ";\n" 604bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " break;\n"; 605bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 606bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson O << "}\n"; 607bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson } 6089255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 609bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" 610bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " \"Invalid alt name index for register!\");\n" 611bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson << " return AsmStrs+RegAsmOffset[RegNo-1];\n" 61205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << "}\n"; 61305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner} 61405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 6152cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingnamespace { 6164962e6143186f6168f5d0ee979bf047651a13124Bill Wendling// IAPrinter - Holds information about an InstAlias. Two InstAliases match if 6174962e6143186f6168f5d0ee979bf047651a13124Bill Wendling// they both have the same conditionals. In which case, we cannot print out the 6184962e6143186f6168f5d0ee979bf047651a13124Bill Wendling// alias for that pattern. 6194962e6143186f6168f5d0ee979bf047651a13124Bill Wendlingclass IAPrinter { 6204962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::vector<std::string> Conds; 6214962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::map<StringRef, unsigned> OpMap; 6224962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::string Result; 6234962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::string AsmString; 624a5b0685142e8d3f5d9b6cf5aee270ebbd796c1baJim Grosbach SmallVector<Record*, 4> ReqFeatures; 6254962e6143186f6168f5d0ee979bf047651a13124Bill Wendlingpublic: 62668ae5b4beab17542b15817815e802475ad1a841fEvan Cheng IAPrinter(std::string R, std::string AS) 62768ae5b4beab17542b15817815e802475ad1a841fEvan Cheng : Result(R), AsmString(AS) {} 6284962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6294962e6143186f6168f5d0ee979bf047651a13124Bill Wendling void addCond(const std::string &C) { Conds.push_back(C); } 6304962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6314962e6143186f6168f5d0ee979bf047651a13124Bill Wendling void addOperand(StringRef Op, unsigned Idx) { OpMap[Op] = Idx; } 6324962e6143186f6168f5d0ee979bf047651a13124Bill Wendling unsigned getOpIndex(StringRef Op) { return OpMap[Op]; } 6334962e6143186f6168f5d0ee979bf047651a13124Bill Wendling bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); } 6344962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 63568ae5b4beab17542b15817815e802475ad1a841fEvan Cheng void print(raw_ostream &O) { 63644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (Conds.empty() && ReqFeatures.empty()) { 63744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "return true;\n"; 63868ae5b4beab17542b15817815e802475ad1a841fEvan Cheng return; 63944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 6403ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 64144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "if ("; 6424962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6434962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<std::string>::iterator 6444962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = Conds.begin(), E = Conds.end(); I != E; ++I) { 6454962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (I != Conds.begin()) { 6464962e6143186f6168f5d0ee979bf047651a13124Bill Wendling O << " &&\n"; 64744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(8); 6484962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6493ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 6504962e6143186f6168f5d0ee979bf047651a13124Bill Wendling O << *I; 6514962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6524962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 65344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << ") {\n"; 65444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "// " << Result << "\n"; 65544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "AsmString = \"" << AsmString << "\";\n"; 6564962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6574962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::map<StringRef, unsigned>::iterator 6584962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = OpMap.begin(), E = OpMap.end(); I != E; ++I) 659f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O.indent(6) << "OpMap.push_back(std::make_pair(\"" << I->first << "\", " 660f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << I->second << "));\n"; 6614962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 66244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "break;\n"; 66344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(4) << '}'; 6644962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6654962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6664962e6143186f6168f5d0ee979bf047651a13124Bill Wendling bool operator==(const IAPrinter &RHS) { 6674962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (Conds.size() != RHS.Conds.size()) 6684962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return false; 6694962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6704962e6143186f6168f5d0ee979bf047651a13124Bill Wendling unsigned Idx = 0; 6714962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<std::string>::iterator 6724962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = Conds.begin(), E = Conds.end(); I != E; ++I) 6734962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (*I != RHS.Conds[Idx++]) 6744962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return false; 6754962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6764962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return true; 6774962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6784962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6794962e6143186f6168f5d0ee979bf047651a13124Bill Wendling bool operator()(const IAPrinter &RHS) { 6804962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (Conds.size() < RHS.Conds.size()) 6814962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return true; 6824962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6834962e6143186f6168f5d0ee979bf047651a13124Bill Wendling unsigned Idx = 0; 6844962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<std::string>::iterator 6854962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = Conds.begin(), E = Conds.end(); I != E; ++I) 6864962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (*I != RHS.Conds[Idx++]) 6874962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return *I < RHS.Conds[Idx++]; 6884962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6894962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return false; 6904962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6914962e6143186f6168f5d0ee979bf047651a13124Bill Wendling}; 6924962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6932cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling} // end anonymous namespace 6942cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 695f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendlingstatic void EmitGetMapOperandNumber(raw_ostream &O) { 696f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << "static unsigned getMapOperandNumber(" 697f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << "const SmallVectorImpl<std::pair<StringRef, unsigned> > &OpMap,\n"; 698f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " StringRef Name) {\n"; 699f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " for (SmallVectorImpl<std::pair<StringRef, unsigned> >::" 700f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << "const_iterator\n"; 701f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " I = OpMap.begin(), E = OpMap.end(); I != E; ++I)\n"; 702f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " if (I->first == Name)\n"; 703f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " return I->second;\n"; 70458609b741301976a2ea3923f4c6494ba1c7e5439Craig Topper O << " llvm_unreachable(\"Operand not in map!\");\n"; 705f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << "}\n\n"; 706f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling} 707f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling 708740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendlingstatic unsigned CountNumOperands(StringRef AsmString) { 709740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling unsigned NumOps = 0; 710740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling std::pair<StringRef, StringRef> ASM = AsmString.split(' '); 711740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 712740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling while (!ASM.second.empty()) { 713740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling ++NumOps; 714740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling ASM = ASM.second.split(' '); 715740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling } 716740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 717740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling return NumOps; 718740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling} 719740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 720393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendlingstatic unsigned CountResultNumOperands(StringRef AsmString) { 721393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling unsigned NumOps = 0; 722393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling std::pair<StringRef, StringRef> ASM = AsmString.split('\t'); 723393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 724393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling if (!ASM.second.empty()) { 725393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling size_t I = ASM.second.find('{'); 726393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling StringRef Str = ASM.second; 727393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling if (I != StringRef::npos) 728393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling Str = ASM.second.substr(I, ASM.second.find('|', I)); 729393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 730393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling ASM = Str.split(' '); 731393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 732393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling do { 733393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling ++NumOps; 734393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling ASM = ASM.second.split(' '); 735393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling } while (!ASM.second.empty()); 736393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling } 737393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 738393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling return NumOps; 739393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling} 740740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 7412cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingvoid AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { 7422cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling CodeGenTarget Target(Records); 7432cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling Record *AsmWriter = Target.getAsmWriter(); 7442cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 745740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling if (!AsmWriter->getValueAsBit("isMCAsmWriter")) 746740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling return; 747740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 7482cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "\n#ifdef PRINT_ALIAS_INSTR\n"; 7492cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "#undef PRINT_ALIAS_INSTR\n\n"; 7502cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7517520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Emit the method that prints the alias instruction. 7527520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 7530d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 7547520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling std::vector<Record*> AllInstAliases = 7557520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling Records.getAllDerivedDefinitions("InstAlias"); 7567520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7577520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Create a map from the qualified name to a list of potential matches. 758b4b26f87fe2309abaa6fceaa71a9d6e812654c9fJim Grosbach std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap; 7597520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling for (std::vector<Record*>::iterator 7607520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { 7617520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); 7627520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const Record *R = *I; 763eef965f04bab483a7d2fd46a7d51559197eda5cfBill Wendling if (!R->getValueAsBit("EmitAlias")) 764eef965f04bab483a7d2fd46a7d51559197eda5cfBill Wendling continue; // We were told not to emit the alias, but to emit the aliasee. 7657520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const DagInit *DI = R->getValueAsDag("ResultInst"); 7667520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const DefInit *Op = dynamic_cast<const DefInit*>(DI->getOperator()); 7677520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling AliasMap[getQualifiedName(Op->getDef())].push_back(Alias); 7687520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 7697520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7703ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling // A map of which conditions need to be met for each instruction operand 7713ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling // before it can be matched to the mnemonic. 772b4b26f87fe2309abaa6fceaa71a9d6e812654c9fJim Grosbach std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap; 7733ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 774b4b26f87fe2309abaa6fceaa71a9d6e812654c9fJim Grosbach for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator 7753ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { 7763ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::vector<CodeGenInstAlias*> &Aliases = I->second; 7773ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 7783ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling for (std::vector<CodeGenInstAlias*>::iterator 7793ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) { 7803ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling const CodeGenInstAlias *CGA = *II; 781740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling unsigned LastOpNo = CGA->ResultInstOperandIndex.size(); 782393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling unsigned NumResultOps = 783393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling CountResultNumOperands(CGA->ResultInst->AsmString); 784740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 785740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling // Don't emit the alias if it has more operands than what it's aliasing. 786393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling if (NumResultOps < CountNumOperands(CGA->AsmString)) 787740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling continue; 788740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 78968ae5b4beab17542b15817815e802475ad1a841fEvan Cheng IAPrinter *IAP = new IAPrinter(CGA->Result->getAsString(), 7903ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling CGA->AsmString); 7913ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 7923ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::string Cond; 7933ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo); 7943ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 7953ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 7963ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::map<StringRef, unsigned> OpMap; 7973ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling bool CantHandle = false; 7983ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 7993ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling for (unsigned i = 0, e = LastOpNo; i != e; ++i) { 8003ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i]; 8013ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 8023ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling switch (RO.Kind) { 8033ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling case CodeGenInstAlias::ResultOperand::K_Record: { 8043ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling const Record *Rec = RO.getRecord(); 8053ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling StringRef ROName = RO.getName(); 8063ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 807bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson 808bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson if (Rec->isSubClassOf("RegisterOperand")) 809bea6f615eefae279e53bbb63a31d2c3c67274c45Owen Anderson Rec = Rec->getValueAsDef("RegClass"); 8103ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (Rec->isSubClassOf("RegisterClass")) { 8113ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()"; 8123ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 8133ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 8143ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (!IAP->isOpMapped(ROName)) { 8153ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addOperand(ROName, i); 816cef670a3a3fd448edfb38d8b513f5aa775257352Benjamin Kramer Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" + 817cef670a3a3fd448edfb38d8b513f5aa775257352Benjamin Kramer CGA->ResultOperands[i].getRecord()->getName() + "RegClassID)" 818cef670a3a3fd448edfb38d8b513f5aa775257352Benjamin Kramer ".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())"; 8193ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 8203ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } else { 8213ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(") + 8223ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(i) + ").getReg() == MI->getOperand(" + 8233ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()"; 8243ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 8253ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8263ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } else { 8273ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); 828740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling // FIXME: We may need to handle these situations. 8293ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling delete IAP; 8303ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP = 0; 8313ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling CantHandle = true; 8323ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 8333ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8343ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 8353ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 8363ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8373ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling case CodeGenInstAlias::ResultOperand::K_Imm: 8383ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(") + 8393ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(i) + ").getImm() == " + 8403ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(CGA->ResultOperands[i].getImm()); 8413ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 8423ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 8433ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling case CodeGenInstAlias::ResultOperand::K_Reg: 844bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach // If this is zero_reg, something's playing tricks we're not 845bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach // equipped to handle. 846bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach if (!CGA->ResultOperands[i].getRegister()) { 847bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach CantHandle = true; 848bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach break; 849bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach } 850bfc9429c2b814469adf3930dda31539d1c3319d8Jim Grosbach 8513ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(") + 8523ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(i) + ").getReg() == " + Target.getName() + 8533ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling "::" + CGA->ResultOperands[i].getRegister()->getName(); 8543ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 8553ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 8563ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8573ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 8583ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (!IAP) break; 8593ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8603ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 8613ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (CantHandle) continue; 862b4b26f87fe2309abaa6fceaa71a9d6e812654c9fJim Grosbach IAPrinterMap[I->first].push_back(IAP); 8633ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8643ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 8653ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 866f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling std::string Header; 867f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling raw_string_ostream HeaderO(Header); 868f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling 869f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling HeaderO << "bool " << Target.getName() << ClassName 870740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling << "::printAliasInstr(const MCInst" 871f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << " *MI, raw_ostream &OS) {\n"; 8723ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 87344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling std::string Cases; 87444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling raw_string_ostream CasesO(Cases); 87544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling 876b4b26f87fe2309abaa6fceaa71a9d6e812654c9fJim Grosbach for (std::map<std::string, std::vector<IAPrinter*> >::iterator 87744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) { 87844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling std::vector<IAPrinter*> &IAPs = I->second; 87944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling std::vector<IAPrinter*> UniqueIAPs; 88044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling 88144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::vector<IAPrinter*>::iterator 88244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling II = IAPs.begin(), IE = IAPs.end(); II != IE; ++II) { 88344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IAPrinter *LHS = *II; 88444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling bool IsDup = false; 88544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::vector<IAPrinter*>::iterator 88644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling III = IAPs.begin(), IIE = IAPs.end(); III != IIE; ++III) { 88744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IAPrinter *RHS = *III; 88844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (LHS != RHS && *LHS == *RHS) { 88944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IsDup = true; 8907520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling break; 8917520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 8927520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 8937520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 89444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (!IsDup) UniqueIAPs.push_back(LHS); 89544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 8967520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 89744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (UniqueIAPs.empty()) continue; 8987520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 899b4b26f87fe2309abaa6fceaa71a9d6e812654c9fJim Grosbach CasesO.indent(2) << "case " << I->first << ":\n"; 9007520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 90144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::vector<IAPrinter*>::iterator 90244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) { 90344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IAPrinter *IAP = *II; 90444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling CasesO.indent(4); 90568ae5b4beab17542b15817815e802475ad1a841fEvan Cheng IAP->print(CasesO); 90644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling CasesO << '\n'; 9077520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 9087520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 909721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher CasesO.indent(4) << "return false;\n"; 91044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 9117520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 912740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling if (CasesO.str().empty()) { 913f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << HeaderO.str(); 914721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher O << " return false;\n"; 91544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "}\n\n"; 91644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "#endif // PRINT_ALIAS_INSTR\n"; 91744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling return; 9187520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 9197520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 920f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling EmitGetMapOperandNumber(O); 921f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling 922f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << HeaderO.str(); 92344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(2) << "StringRef AsmString;\n"; 924f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O.indent(2) << "SmallVector<std::pair<StringRef, unsigned>, 4> OpMap;\n"; 92544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(2) << "switch (MI->getOpcode()) {\n"; 926721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher O.indent(2) << "default: return false;\n"; 92744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << CasesO.str(); 92844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(2) << "}\n\n"; 9297520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 9307520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Code that prints the alias, replacing the operands with the ones from the 9317520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // MCInst. 9327520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n"; 9337520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " OS << '\\t' << ASM.first;\n"; 9347520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 9357520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " if (!ASM.second.empty()) {\n"; 9367520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " OS << '\\t';\n"; 9377520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " for (StringRef::iterator\n"; 9387520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n"; 9397520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " if (*I == '$') {\n"; 9407520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " StringRef::iterator Start = ++I;\n"; 9417520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " while (I != E &&\n"; 9427520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " ((*I >= 'a' && *I <= 'z') ||\n"; 9437520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " (*I >= 'A' && *I <= 'Z') ||\n"; 9447520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " (*I >= '0' && *I <= '9') ||\n"; 9457520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " *I == '_'))\n"; 9467520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " ++I;\n"; 9477520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " StringRef Name(Start, I - Start);\n"; 948f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " printOperand(MI, getMapOperandNumber(OpMap, Name), OS);\n"; 9497520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " } else {\n"; 9507520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " OS << *I++;\n"; 9517520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n"; 9527520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n"; 9537520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n\n"; 954016c679c50e13532a30d80b59232e4b82ab807bfJim Grosbach 955721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher O << " return true;\n"; 9567520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "}\n\n"; 9577520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 9587520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "#endif // PRINT_ALIAS_INSTR\n"; 9597520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling} 96005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 96105af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::run(raw_ostream &O) { 96205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitPrintInstruction(O); 96305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitGetRegisterName(O); 9647520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling EmitPrintAliasInstruction(O); 96505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner} 96605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 9676f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 9686f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesennamespace llvm { 9696f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 9706f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesenvoid EmitAsmWriter(RecordKeeper &RK, raw_ostream &OS) { 9716f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen emitSourceFileHeader("Assembly Writer Source Fragment", OS); 9726f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen AsmWriterEmitter(RK).run(OS); 9736f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} 9746f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen 9756f36fa981a59461466e12e5056ba209d289b81b1Jakob Stoklund Olesen} // End llvm namespace 976