AsmWriterEmitter.cpp revision 9255b8d349768a02b2d139a43984c9b544098122
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 152e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "AsmWriterEmitter.h" 16d32c02f3145c8d5114c9bd367e9ff15f4aed2e15Sean Callanan#include "AsmWriterInst.h" 172e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "CodeGenTarget.h" 18175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner#include "Record.h" 1944da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner#include "StringToOffsetTable.h" 20bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/Debug.h" 21bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/MathExtras.h" 22615ed993e115f8bc97ff0678aa861629fec93880Jeff Cohen#include <algorithm> 232e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnerusing namespace llvm; 242e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 2538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattnerstatic void PrintCases(std::vector<std::pair<std::string, 261a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar AsmWriterOperand> > &OpsToPrint, raw_ostream &O) { 2738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << " case " << OpsToPrint.back().first << ": "; 2838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterOperand TheOp = OpsToPrint.back().second; 2938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.pop_back(); 3038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 3138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Check to see if any other operands are identical in this list, and if so, 3238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // emit a case label for them. 3338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner for (unsigned i = OpsToPrint.size(); i != 0; --i) 3438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner if (OpsToPrint[i-1].second == TheOp) { 3538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "\n case " << OpsToPrint[i-1].first << ": "; 3638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.erase(OpsToPrint.begin()+i-1); 3738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner } 3838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 3938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Finally, emit the code. 40bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << TheOp.getCode(); 4138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "break;\n"; 4238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner} 4338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 44870c016934bacf43995d89531b166ae095ee3675Chris Lattner 45870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// EmitInstructions - Emit the last instruction in the vector and any other 46870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// instructions that are suitably similar to it. 47870c016934bacf43995d89531b166ae095ee3675Chris Lattnerstatic void EmitInstructions(std::vector<AsmWriterInst> &Insts, 481a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &O) { 49870c016934bacf43995d89531b166ae095ee3675Chris Lattner AsmWriterInst FirstInst = Insts.back(); 50870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.pop_back(); 51870c016934bacf43995d89531b166ae095ee3675Chris Lattner 52870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::vector<AsmWriterInst> SimilarInsts; 53870c016934bacf43995d89531b166ae095ee3675Chris Lattner unsigned DifferingOperand = ~0; 54870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = Insts.size(); i != 0; --i) { 55f876668518097413a904537ce9d249953987508cChris Lattner unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst); 56f876668518097413a904537ce9d249953987508cChris Lattner if (DiffOp != ~1U) { 57870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (DifferingOperand == ~0U) // First match! 58870c016934bacf43995d89531b166ae095ee3675Chris Lattner DifferingOperand = DiffOp; 59870c016934bacf43995d89531b166ae095ee3675Chris Lattner 60870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this differs in the same operand as the rest of the instructions in 61870c016934bacf43995d89531b166ae095ee3675Chris Lattner // this class, move it to the SimilarInsts list. 62f876668518097413a904537ce9d249953987508cChris Lattner if (DifferingOperand == DiffOp || DiffOp == ~0U) { 63870c016934bacf43995d89531b166ae095ee3675Chris Lattner SimilarInsts.push_back(Insts[i-1]); 64870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.erase(Insts.begin()+i-1); 65870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 66870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 67870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 68870c016934bacf43995d89531b166ae095ee3675Chris Lattner 69a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << FirstInst.CGI->Namespace << "::" 70870c016934bacf43995d89531b166ae095ee3675Chris Lattner << FirstInst.CGI->TheDef->getName() << ":\n"; 71870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i) 72a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << SimilarInsts[i].CGI->Namespace << "::" 73870c016934bacf43995d89531b166ae095ee3675Chris Lattner << SimilarInsts[i].CGI->TheDef->getName() << ":\n"; 74870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) { 75870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (i != DifferingOperand) { 76870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If the operand is the same for all instructions, just print it. 77bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << " " << FirstInst.Operands[i].getCode(); 78870c016934bacf43995d89531b166ae095ee3675Chris Lattner } else { 79870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this is the operand that varies between all of the instructions, 80870c016934bacf43995d89531b166ae095ee3675Chris Lattner // emit a switch for just this operand now. 81870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " switch (MI->getOpcode()) {\n"; 8238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint; 83a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" + 8438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.CGI->TheDef->getName(), 8538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.Operands[i])); 863da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 87870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { 8838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterInst &AWI = SimilarInsts[si]; 89a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+ 9038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.CGI->TheDef->getName(), 9138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.Operands[i])); 92870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 9338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::reverse(OpsToPrint.begin(), OpsToPrint.end()); 9438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner while (!OpsToPrint.empty()) 9538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner PrintCases(OpsToPrint, O); 96870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " }"; 97870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 98870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << "\n"; 99870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 100870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " break;\n"; 101870c016934bacf43995d89531b166ae095ee3675Chris Lattner} 102b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 103bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattnervoid AsmWriterEmitter:: 1049255b8d349768a02b2d139a43984c9b544098122Jim GrosbachFindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 10596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstIdxs, 10696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstOpsUsed) const { 107195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner InstIdxs.assign(NumberedInstructions.size(), ~0U); 1089255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 109bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // This vector parallels UniqueOperandCommands, keeping track of which 110bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // instructions each case are used for. It is a comma separated string of 111bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // enums. 112bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> InstrsForCase; 113bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.resize(UniqueOperandCommands.size()); 11496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.assign(UniqueOperandCommands.size(), 0); 1159255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 116bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 117bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner const AsmWriterInst *Inst = getAsmWriterInstByID(i); 118b9449d663921fc27d503d048028937c5a19b6f8bBill Wendling if (Inst == 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc. 1199255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 120bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Command; 121b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst->Operands.empty()) 122bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner continue; // Instruction already done. 123191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 124b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner Command = " " + Inst->Operands[0].getCode() + "\n"; 125191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 126bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Check to see if we already have 'Command' in UniqueOperandCommands. 127bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If not, add it. 128bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner bool FoundIt = false; 129bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx) 130bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands[idx] == Command) { 131bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = idx; 132bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += ", "; 133bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += Inst->CGI->TheDef->getName(); 134bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner FoundIt = true; 135bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 136bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 137bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!FoundIt) { 138bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = UniqueOperandCommands.size(); 139bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands.push_back(Command); 140bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.push_back(Inst->CGI->TheDef->getName()); 14196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 14296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // This command matches one operand so far. 14396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.push_back(1); 14496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 14596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 1469255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 14796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // For each entry of UniqueOperandCommands, there is a set of instructions 14896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // that uses it. If the next command of all instructions in the set are 14996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // identical, fold it into the command. 15096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size(); 15196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner CommandIdx != e; ++CommandIdx) { 1529255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 15396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned Op = 1; ; ++Op) { 15496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Scan for the first instruction in the set. 15596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned>::iterator NIT = 15696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx); 15796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (NIT == InstIdxs.end()) break; // No commonality. 15896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 15996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // If this instruction has no more operands, we isn't anything to merge 16096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // into this command. 1619255b8d349768a02b2d139a43984c9b544098122Jim Grosbach const AsmWriterInst *FirstInst = 16296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 16396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!FirstInst || FirstInst->Operands.size() == Op) 16496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 16596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 16696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Otherwise, scan to see if all of the other instructions in this command 16796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // set share the operand. 16896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner bool AllSame = true; 169c8d060503619d32012167d2427891a85e116f3d2David Greene // Keep track of the maximum, number of operands or any 170c8d060503619d32012167d2427891a85e116f3d2David Greene // instruction we see in the group. 171c8d060503619d32012167d2427891a85e116f3d2David Greene size_t MaxSize = FirstInst->Operands.size(); 172c8d060503619d32012167d2427891a85e116f3d2David Greene 17396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx); 17496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT != InstIdxs.end(); 17596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) { 17696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, found another instruction in this command set. If the operand 17796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // matches, we're ok, otherwise bail out. 1789255b8d349768a02b2d139a43984c9b544098122Jim Grosbach const AsmWriterInst *OtherInst = 17996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 180c8d060503619d32012167d2427891a85e116f3d2David Greene 181c8d060503619d32012167d2427891a85e116f3d2David Greene if (OtherInst && 182c8d060503619d32012167d2427891a85e116f3d2David Greene OtherInst->Operands.size() > FirstInst->Operands.size()) 183c8d060503619d32012167d2427891a85e116f3d2David Greene MaxSize = std::max(MaxSize, OtherInst->Operands.size()); 184c8d060503619d32012167d2427891a85e116f3d2David Greene 18596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!OtherInst || OtherInst->Operands.size() == Op || 18696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner OtherInst->Operands[Op] != FirstInst->Operands[Op]) { 18796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner AllSame = false; 18896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 18996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 19096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 19196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!AllSame) break; 1929255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 19396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, everything in this command set has the same next operand. Add it 19496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // to UniqueOperandCommands and remember that it was consumed. 19596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n"; 1969255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 19796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner UniqueOperandCommands[CommandIdx] += Command; 19896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed[CommandIdx]++; 199bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 200bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 2019255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 202bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Prepend some of the instructions each case is used for onto the case val. 203bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) { 204bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Instrs = InstrsForCase[i]; 205bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (Instrs.size() > 70) { 206bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs.erase(Instrs.begin()+70, Instrs.end()); 207bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs += "..."; 208bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 2099255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 210bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!Instrs.empty()) 2119255b8d349768a02b2d139a43984c9b544098122Jim Grosbach UniqueOperandCommands[i] = " // " + Instrs + "\n" + 212bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands[i]; 213bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 214bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner} 215bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 216bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 2179bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbarstatic void UnescapeString(std::string &Str) { 2189bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar for (unsigned i = 0; i != Str.size(); ++i) { 2199bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar if (Str[i] == '\\' && i != Str.size()-1) { 2209bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar switch (Str[i+1]) { 2219bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar default: continue; // Don't execute the code after the switch. 2229bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'a': Str[i] = '\a'; break; 2239bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'b': Str[i] = '\b'; break; 2249bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'e': Str[i] = 27; break; 2259bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'f': Str[i] = '\f'; break; 2269bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'n': Str[i] = '\n'; break; 2279bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'r': Str[i] = '\r'; break; 2289bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 't': Str[i] = '\t'; break; 2299bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'v': Str[i] = '\v'; break; 2309bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '"': Str[i] = '\"'; break; 2319bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '\'': Str[i] = '\''; break; 2329bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '\\': Str[i] = '\\'; break; 2339bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2349bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar // Nuke the second character. 2359bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar Str.erase(Str.begin()+i+1); 2369bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2379bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2389bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar} 2399bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar 24005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner/// EmitPrintInstruction - Generate the code for the "printInstruction" method 24105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner/// implementation. 24205af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 2432e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner CodeGenTarget Target; 244175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner Record *AsmWriter = Target.getAsmWriter(); 245953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 2469255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2472e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << 2482e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// printInstruction - This method is automatically generated by tablegen\n" 24905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// from the instruction set description.\n" 25041aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner "void " << Target.getName() << ClassName 25135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner << "::printInstruction(const MachineInstr *MI, raw_ostream &O) {\n"; 2522e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 2535765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner std::vector<AsmWriterInst> Instructions; 2545765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 2552e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 2562e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner E = Target.inst_end(); I != E; ++I) 2576a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner if (!(*I)->AsmString.empty() && 2586a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner (*I)->TheDef->getName() != "PHI") 259d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan Instructions.push_back( 2609255b8d349768a02b2d139a43984c9b544098122Jim Grosbach AsmWriterInst(**I, 261d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("Variant"), 262d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("FirstOperandColumn"), 263d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("OperandSpacing"))); 2645765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 265bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Get the instruction numbering. 266f65027842e82027dd6e8020586a299aaa548e355Chris Lattner NumberedInstructions = Target.getInstructionsByEnumValue(); 2679255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2686af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not 2696af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // all machine instructions are necessarily being printed, so there may be 2706af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // target instructions not in this map. 2716af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) 2726af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); 2736af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 2746af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Build an aggregate string, and build a table of offsets into it. 2753200fc9badda8964fac571995bd74a3954977ddcChris Lattner StringToOffsetTable StringTable; 2769255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 277259bda48e2c6b886f707513781f1b76595d4ad0dChris Lattner /// OpcodeInfo - This encodes the index of the string to use for the first 2785561640043666174a1e4d828107702a8992e59f6Chris Lattner /// chunk of the output as well as indices used for operand printing. 2795561640043666174a1e4d828107702a8992e59f6Chris Lattner std::vector<unsigned> OpcodeInfo; 2809255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2815561640043666174a1e4d828107702a8992e59f6Chris Lattner unsigned MaxStringIdx = 0; 2826af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 2836af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 2846af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner unsigned Idx; 285a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner if (AWI == 0) { 2866af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Something not handled by the asmwriter printer. 2873200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = ~0U; 2889255b8d349768a02b2d139a43984c9b544098122Jim Grosbach } else if (AWI->Operands[0].OperandType != 289a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AsmWriterOperand::isLiteralTextOperand || 290a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AWI->Operands[0].Str.empty()) { 291a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner // Something handled by the asmwriter printer, but with no leading string. 2923200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = StringTable.GetOrAddStringOffset(""); 2936af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } else { 2943200fc9badda8964fac571995bd74a3954977ddcChris Lattner std::string Str = AWI->Operands[0].Str; 2953200fc9badda8964fac571995bd74a3954977ddcChris Lattner UnescapeString(Str); 2963200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = StringTable.GetOrAddStringOffset(Str); 2973200fc9badda8964fac571995bd74a3954977ddcChris Lattner MaxStringIdx = std::max(MaxStringIdx, Idx); 2989255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2996af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Nuke the string from the operand list. It is now handled! 3006af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AWI->Operands.erase(AWI->Operands.begin()); 3016af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 3029255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3033200fc9badda8964fac571995bd74a3954977ddcChris Lattner // Bias offset by one since we want 0 as a sentinel. 3043200fc9badda8964fac571995bd74a3954977ddcChris Lattner OpcodeInfo.push_back(Idx+1); 305bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3069255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3075561640043666174a1e4d828107702a8992e59f6Chris Lattner // Figure out how many bits we used for the string index. 3083200fc9badda8964fac571995bd74a3954977ddcChris Lattner unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2); 3099255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 310bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // To reduce code size, we compactify common instructions into a few bits 311bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // in the opcode-indexed table. 312b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner unsigned BitsLeft = 32-AsmStrBits; 313bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 314bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::vector<std::string> > TableDrivenOperandPrinters; 3159255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 316b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner while (1) { 317bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> UniqueOperandCommands; 318bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<unsigned> InstIdxs; 31996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> NumInstOpsHandled; 32096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs, 32196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NumInstOpsHandled); 3229255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 323bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we ran out of operands to print, we're done. 324bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands.empty()) break; 3259255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 326bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 327bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 328bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size()); 3299255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 330bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we don't have enough bits for this operand, don't include it. 331bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (NumBits > BitsLeft) { 332569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner DEBUG(errs() << "Not enough bits to densely encode " << NumBits 333569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner << " more bits\n"); 334bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 335bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3369255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 337bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Otherwise, we can include this in the initial lookup table. Add it in. 338bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 339bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i) 340195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner if (InstIdxs[i] != ~0U) 341195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits); 3429255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 343b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remove the info about this operand. 344b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 345b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (AsmWriterInst *Inst = getAsmWriterInstByID(i)) 34696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!Inst->Operands.empty()) { 34796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner unsigned NumOps = NumInstOpsHandled[InstIdxs[i]]; 3480a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner assert(NumOps <= Inst->Operands.size() && 3490a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner "Can't remove this many ops!"); 35096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.erase(Inst->Operands.begin(), 35196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.begin()+NumOps); 35296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 353b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner } 3549255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 355b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remember the handlers for this set of operands. 356bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner TableDrivenOperandPrinters.push_back(UniqueOperandCommands); 357bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3589255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3599255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3609255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3615561640043666174a1e4d828107702a8992e59f6Chris Lattner O<<" static const unsigned OpInfo[] = {\n"; 362bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 363b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " " << OpcodeInfo[i] << "U,\t// " 3645561640043666174a1e4d828107702a8992e59f6Chris Lattner << NumberedInstructions[i]->TheDef->getName() << "\n"; 3656af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 366bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Add a dummy entry so the array init doesn't end with a comma. 3675561640043666174a1e4d828107702a8992e59f6Chris Lattner O << " 0U\n"; 3686af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " };\n\n"; 3699255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3706af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Emit the string itself. 3713200fc9badda8964fac571995bd74a3954977ddcChris Lattner O << " const char *AsmStrs = \n"; 3723200fc9badda8964fac571995bd74a3954977ddcChris Lattner StringTable.EmitString(O); 3733200fc9badda8964fac571995bd74a3954977ddcChris Lattner O << ";\n\n"; 3746af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 3754eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng O << " O << \"\\t\";\n\n"; 3764eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng 3776af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " // Emit the opcode for the instruction.\n" 3785561640043666174a1e4d828107702a8992e59f6Chris Lattner << " unsigned Bits = OpInfo[MI->getOpcode()];\n" 37941aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" 3803200fc9badda8964fac571995bd74a3954977ddcChris Lattner << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; 381a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 382bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Output the table driven operand information. 383b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner BitsLeft = 32-AsmStrBits; 384bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) { 385bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> &Commands = TableDrivenOperandPrinters[i]; 386f876668518097413a904537ce9d249953987508cChris Lattner 387bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 388bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 389bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(Commands.size()); 390bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner assert(NumBits <= BitsLeft && "consistency error"); 3919255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 392bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Emit code to extract this field from Bits. 393bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 3949255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 395bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << "\n // Fragment " << i << " encoded into " << NumBits 396e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " bits for " << Commands.size() << " unique commands.\n"; 3979255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 39896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (Commands.size() == 2) { 399e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Emit two possibilitys with if/else. 400e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 401e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 402e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[1] 403e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " } else {\n" 404e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[0] 405e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " }\n\n"; 406168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher } else if (Commands.size() == 1) { 407168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher // Emit a single possibility. 408168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher O << Commands[0] << "\n\n"; 409e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } else { 410e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 411e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 412e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " default: // unreachable.\n"; 4139255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 414e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Print out all the cases. 415e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner for (unsigned i = 0, e = Commands.size(); i != e; ++i) { 416e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " case " << i << ":\n"; 417e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << Commands[i]; 418e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " break;\n"; 419e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } 420e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " }\n\n"; 421bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 422bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 4239255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 424b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Okay, delete instructions with no operand info left. 425bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { 426bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Entire instruction has been emitted? 427bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner AsmWriterInst &Inst = Instructions[i]; 428b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst.Operands.empty()) { 429bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instructions.erase(Instructions.begin()+i); 430b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner --i; --e; 431bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 432bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 433bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 4349255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 435bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Because this is a vector, we want to emit from the end. Reverse all of the 436870c016934bacf43995d89531b166ae095ee3675Chris Lattner // elements in the vector. 437870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::reverse(Instructions.begin(), Instructions.end()); 4389255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4399255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 440700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // Now that we've emitted all of the operand info that fit into 32 bits, emit 441700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // information for those instructions that are left. This is a less dense 442700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // encoding, but we expect the main 32-bit table to handle the majority of 443700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // instructions. 444b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner if (!Instructions.empty()) { 445b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner // Find the opcode # of inline asm. 446b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " switch (MI->getOpcode()) {\n"; 447b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner while (!Instructions.empty()) 448b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner EmitInstructions(Instructions, O); 449870c016934bacf43995d89531b166ae095ee3675Chris Lattner 450b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " }\n"; 45141aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner O << " return;\n"; 452b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner } 453c8d060503619d32012167d2427891a85e116f3d2David Greene 4540a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner O << "}\n"; 4552e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner} 45605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 45705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 45805af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 45905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner CodeGenTarget Target; 46005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner Record *AsmWriter = Target.getAsmWriter(); 46105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 46205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner const std::vector<CodeGenRegister> &Registers = Target.getRegisters(); 4639255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 464f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner StringToOffsetTable StringTable; 46505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner O << 46605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" 46705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// from the register set description. This returns the assembler name\n" 46805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// for the specified register.\n" 46905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "const char *" << Target.getName() << ClassName 470d95148f073c31924f275a34296da52a7cdefad91Chris Lattner << "::getRegisterName(unsigned RegNo) {\n" 47105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << " assert(RegNo && RegNo < " << (Registers.size()+1) 47205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << " && \"Invalid register number!\");\n" 47305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << "\n" 474f96271afed5504d75a71e9dd9ed89152645604aaChris Lattner << " static const unsigned RegAsmOffset[] = {"; 47505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 47605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner const CodeGenRegister &Reg = Registers[i]; 47705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 47805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner std::string AsmName = Reg.TheDef->getValueAsString("AsmName"); 47905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner if (AsmName.empty()) 48005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner AsmName = Reg.getName(); 4819255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4829255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 483f96271afed5504d75a71e9dd9ed89152645604aaChris Lattner if ((i % 14) == 0) 484f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << "\n "; 4859255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 486f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << StringTable.GetOrAddStringOffset(AsmName) << ", "; 48705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner } 488f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << "0\n" 48905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << " };\n" 490f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner << "\n"; 4919255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 492f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << " const char *AsmStrs =\n"; 493f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner StringTable.EmitString(O); 494f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << ";\n"; 4959255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 496f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << " return AsmStrs+RegAsmOffset[RegNo-1];\n" 49705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << "}\n"; 49805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner} 49905af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 5000d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattnervoid AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) { 5010d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner CodeGenTarget Target; 5020d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner Record *AsmWriter = Target.getAsmWriter(); 5030d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 5040d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 505f65027842e82027dd6e8020586a299aaa548e355Chris Lattner const std::vector<const CodeGenInstruction*> &NumberedInstructions = 506f65027842e82027dd6e8020586a299aaa548e355Chris Lattner Target.getInstructionsByEnumValue(); 5079255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5080d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner StringToOffsetTable StringTable; 5090d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << 5100d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"\n\n#ifdef GET_INSTRUCTION_NAME\n" 5110d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"#undef GET_INSTRUCTION_NAME\n\n" 5120d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"/// getInstructionName: This method is automatically generated by tblgen\n" 5130d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"/// from the instruction set description. This returns the enum name of the\n" 5140d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"/// specified instruction.\n" 5150d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner "const char *" << Target.getName() << ClassName 5160d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "::getInstructionName(unsigned Opcode) {\n" 5170d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " assert(Opcode < " << NumberedInstructions.size() 5180d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " && \"Invalid instruction number!\");\n" 5190d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "\n" 5200d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " static const unsigned InstAsmOffset[] = {"; 5210d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 5220d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner const CodeGenInstruction &Inst = *NumberedInstructions[i]; 5239255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5240d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner std::string AsmName = Inst.TheDef->getName(); 5250d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner if ((i % 14) == 0) 5260d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << "\n "; 5279255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5280d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << StringTable.GetOrAddStringOffset(AsmName) << ", "; 5290d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner } 5300d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << "0\n" 5310d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " };\n" 5320d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "\n"; 5339255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5340d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << " const char *Strs =\n"; 5350d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner StringTable.EmitString(O); 5360d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << ";\n"; 5379255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5380d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << " return Strs+InstAsmOffset[Opcode];\n" 5390d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "}\n\n#endif\n"; 5400d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner} 5410d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 5420d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 54305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 54405af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::run(raw_ostream &O) { 54505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitSourceFileHeader("Assembly Writer Source Fragment", O); 5469255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 54705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitPrintInstruction(O); 54805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitGetRegisterName(O); 5490d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner EmitGetInstructionName(O); 55005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner} 55105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 552