AsmWriterEmitter.cpp revision 0b6a44afb92fed0365b6709c1f46b0c5e49e1a72
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" 170b6a44afb92fed0365b6709c1f46b0c5e49e1a72Jim Grosbach#include "Error.h" 182e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "CodeGenTarget.h" 19175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner#include "Record.h" 2044da5fbf97e31d5cf8ca6ebf99c613d116f51445Chris Lattner#include "StringToOffsetTable.h" 21bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/Debug.h" 22bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/MathExtras.h" 23615ed993e115f8bc97ff0678aa861629fec93880Jeff Cohen#include <algorithm> 242e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnerusing namespace llvm; 252e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 2638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattnerstatic void PrintCases(std::vector<std::pair<std::string, 271a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar AsmWriterOperand> > &OpsToPrint, raw_ostream &O) { 2838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << " case " << OpsToPrint.back().first << ": "; 2938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterOperand TheOp = OpsToPrint.back().second; 3038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.pop_back(); 3138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 3238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Check to see if any other operands are identical in this list, and if so, 3338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // emit a case label for them. 3438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner for (unsigned i = OpsToPrint.size(); i != 0; --i) 3538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner if (OpsToPrint[i-1].second == TheOp) { 3638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "\n case " << OpsToPrint[i-1].first << ": "; 3738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.erase(OpsToPrint.begin()+i-1); 3838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner } 3938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 4038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Finally, emit the code. 41bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << TheOp.getCode(); 4238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "break;\n"; 4338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner} 4438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 45870c016934bacf43995d89531b166ae095ee3675Chris Lattner 46870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// EmitInstructions - Emit the last instruction in the vector and any other 47870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// instructions that are suitably similar to it. 48870c016934bacf43995d89531b166ae095ee3675Chris Lattnerstatic void EmitInstructions(std::vector<AsmWriterInst> &Insts, 491a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &O) { 50870c016934bacf43995d89531b166ae095ee3675Chris Lattner AsmWriterInst FirstInst = Insts.back(); 51870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.pop_back(); 52870c016934bacf43995d89531b166ae095ee3675Chris Lattner 53870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::vector<AsmWriterInst> SimilarInsts; 54870c016934bacf43995d89531b166ae095ee3675Chris Lattner unsigned DifferingOperand = ~0; 55870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = Insts.size(); i != 0; --i) { 56f876668518097413a904537ce9d249953987508cChris Lattner unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst); 57f876668518097413a904537ce9d249953987508cChris Lattner if (DiffOp != ~1U) { 58870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (DifferingOperand == ~0U) // First match! 59870c016934bacf43995d89531b166ae095ee3675Chris Lattner DifferingOperand = DiffOp; 60870c016934bacf43995d89531b166ae095ee3675Chris Lattner 61870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this differs in the same operand as the rest of the instructions in 62870c016934bacf43995d89531b166ae095ee3675Chris Lattner // this class, move it to the SimilarInsts list. 63f876668518097413a904537ce9d249953987508cChris Lattner if (DifferingOperand == DiffOp || DiffOp == ~0U) { 64870c016934bacf43995d89531b166ae095ee3675Chris Lattner SimilarInsts.push_back(Insts[i-1]); 65870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.erase(Insts.begin()+i-1); 66870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 67870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 68870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 69870c016934bacf43995d89531b166ae095ee3675Chris Lattner 70a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << FirstInst.CGI->Namespace << "::" 71870c016934bacf43995d89531b166ae095ee3675Chris Lattner << FirstInst.CGI->TheDef->getName() << ":\n"; 72870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i) 73a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << SimilarInsts[i].CGI->Namespace << "::" 74870c016934bacf43995d89531b166ae095ee3675Chris Lattner << SimilarInsts[i].CGI->TheDef->getName() << ":\n"; 75870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) { 76870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (i != DifferingOperand) { 77870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If the operand is the same for all instructions, just print it. 78bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << " " << FirstInst.Operands[i].getCode(); 79870c016934bacf43995d89531b166ae095ee3675Chris Lattner } else { 80870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this is the operand that varies between all of the instructions, 81870c016934bacf43995d89531b166ae095ee3675Chris Lattner // emit a switch for just this operand now. 82870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " switch (MI->getOpcode()) {\n"; 8338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint; 84a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" + 8538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.CGI->TheDef->getName(), 8638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.Operands[i])); 873da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 88870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { 8938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterInst &AWI = SimilarInsts[si]; 90a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+ 9138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.CGI->TheDef->getName(), 9238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.Operands[i])); 93870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 9438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::reverse(OpsToPrint.begin(), OpsToPrint.end()); 9538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner while (!OpsToPrint.empty()) 9638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner PrintCases(OpsToPrint, O); 97870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " }"; 98870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 99870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << "\n"; 100870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 101870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " break;\n"; 102870c016934bacf43995d89531b166ae095ee3675Chris Lattner} 103b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 104bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattnervoid AsmWriterEmitter:: 1059255b8d349768a02b2d139a43984c9b544098122Jim GrosbachFindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 10696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstIdxs, 10796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstOpsUsed) const { 108195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner InstIdxs.assign(NumberedInstructions.size(), ~0U); 1099255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 110bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // This vector parallels UniqueOperandCommands, keeping track of which 111bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // instructions each case are used for. It is a comma separated string of 112bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // enums. 113bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> InstrsForCase; 114bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.resize(UniqueOperandCommands.size()); 11596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.assign(UniqueOperandCommands.size(), 0); 1169255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 117bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 118bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner const AsmWriterInst *Inst = getAsmWriterInstByID(i); 119b9449d663921fc27d503d048028937c5a19b6f8bBill Wendling if (Inst == 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc. 1209255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 121bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Command; 122b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst->Operands.empty()) 123bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner continue; // Instruction already done. 124191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 125b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner Command = " " + Inst->Operands[0].getCode() + "\n"; 126191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 127bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Check to see if we already have 'Command' in UniqueOperandCommands. 128bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If not, add it. 129bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner bool FoundIt = false; 130bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx) 131bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands[idx] == Command) { 132bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = idx; 133bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += ", "; 134bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += Inst->CGI->TheDef->getName(); 135bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner FoundIt = true; 136bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 137bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 138bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!FoundIt) { 139bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = UniqueOperandCommands.size(); 140bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands.push_back(Command); 141bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.push_back(Inst->CGI->TheDef->getName()); 14296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 14396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // This command matches one operand so far. 14496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.push_back(1); 14596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 14696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 1479255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 14896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // For each entry of UniqueOperandCommands, there is a set of instructions 14996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // that uses it. If the next command of all instructions in the set are 15096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // identical, fold it into the command. 15196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size(); 15296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner CommandIdx != e; ++CommandIdx) { 1539255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 15496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned Op = 1; ; ++Op) { 15596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Scan for the first instruction in the set. 15696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned>::iterator NIT = 15796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx); 15896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (NIT == InstIdxs.end()) break; // No commonality. 15996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 16096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // If this instruction has no more operands, we isn't anything to merge 16196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // into this command. 1629255b8d349768a02b2d139a43984c9b544098122Jim Grosbach const AsmWriterInst *FirstInst = 16396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 16496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!FirstInst || FirstInst->Operands.size() == Op) 16596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 16696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 16796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Otherwise, scan to see if all of the other instructions in this command 16896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // set share the operand. 16996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner bool AllSame = true; 170c8d060503619d32012167d2427891a85e116f3d2David Greene // Keep track of the maximum, number of operands or any 171c8d060503619d32012167d2427891a85e116f3d2David Greene // instruction we see in the group. 172c8d060503619d32012167d2427891a85e116f3d2David Greene size_t MaxSize = FirstInst->Operands.size(); 173c8d060503619d32012167d2427891a85e116f3d2David Greene 17496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx); 17596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT != InstIdxs.end(); 17696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) { 17796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, found another instruction in this command set. If the operand 17896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // matches, we're ok, otherwise bail out. 1799255b8d349768a02b2d139a43984c9b544098122Jim Grosbach const AsmWriterInst *OtherInst = 18096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 181c8d060503619d32012167d2427891a85e116f3d2David Greene 182c8d060503619d32012167d2427891a85e116f3d2David Greene if (OtherInst && 183c8d060503619d32012167d2427891a85e116f3d2David Greene OtherInst->Operands.size() > FirstInst->Operands.size()) 184c8d060503619d32012167d2427891a85e116f3d2David Greene MaxSize = std::max(MaxSize, OtherInst->Operands.size()); 185c8d060503619d32012167d2427891a85e116f3d2David Greene 18696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!OtherInst || OtherInst->Operands.size() == Op || 18796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner OtherInst->Operands[Op] != FirstInst->Operands[Op]) { 18896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner AllSame = false; 18996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 19096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 19196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 19296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!AllSame) break; 1939255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 19496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, everything in this command set has the same next operand. Add it 19596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // to UniqueOperandCommands and remember that it was consumed. 19696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n"; 1979255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 19896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner UniqueOperandCommands[CommandIdx] += Command; 19996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed[CommandIdx]++; 200bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 201bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 2029255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 203bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Prepend some of the instructions each case is used for onto the case val. 204bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) { 205bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Instrs = InstrsForCase[i]; 206bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (Instrs.size() > 70) { 207bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs.erase(Instrs.begin()+70, Instrs.end()); 208bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs += "..."; 209bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 2109255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 211bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!Instrs.empty()) 2129255b8d349768a02b2d139a43984c9b544098122Jim Grosbach UniqueOperandCommands[i] = " // " + Instrs + "\n" + 213bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands[i]; 214bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 215bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner} 216bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 217bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 2189bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbarstatic void UnescapeString(std::string &Str) { 2199bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar for (unsigned i = 0; i != Str.size(); ++i) { 2209bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar if (Str[i] == '\\' && i != Str.size()-1) { 2219bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar switch (Str[i+1]) { 2229bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar default: continue; // Don't execute the code after the switch. 2239bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'a': Str[i] = '\a'; break; 2249bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'b': Str[i] = '\b'; break; 2259bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'e': Str[i] = 27; break; 2269bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'f': Str[i] = '\f'; break; 2279bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'n': Str[i] = '\n'; break; 2289bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'r': Str[i] = '\r'; break; 2299bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 't': Str[i] = '\t'; break; 2309bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case 'v': Str[i] = '\v'; break; 2319bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '"': Str[i] = '\"'; break; 2329bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '\'': Str[i] = '\''; break; 2339bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar case '\\': Str[i] = '\\'; break; 2349bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2359bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar // Nuke the second character. 2369bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar Str.erase(Str.begin()+i+1); 2379bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2389bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar } 2399bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar} 2409bd34602fbe945cc2ed81f8f8ac7de59f4679038Daniel Dunbar 24105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner/// EmitPrintInstruction - Generate the code for the "printInstruction" method 24205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner/// implementation. 24305af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 24467db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 245175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner Record *AsmWriter = Target.getAsmWriter(); 246953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 247ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter"); 248ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr"; 2499255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2502e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << 2512e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// printInstruction - This method is automatically generated by tablegen\n" 25205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// from the instruction set description.\n" 25341aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner "void " << Target.getName() << ClassName 254ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach << "::printInstruction(const " << MachineInstrClassName 255ca96a861655d3fcfc5ff047e249703930c8330bcJim Grosbach << " *MI, raw_ostream &O) {\n"; 2562e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 2575765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner std::vector<AsmWriterInst> Instructions; 2585765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 2592e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 2602e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner E = Target.inst_end(); I != E; ++I) 2616a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner if (!(*I)->AsmString.empty() && 2626a91b18e5777f39e52e93221453abfa4553b6f93Chris Lattner (*I)->TheDef->getName() != "PHI") 263d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan Instructions.push_back( 2649255b8d349768a02b2d139a43984c9b544098122Jim Grosbach AsmWriterInst(**I, 265d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("Variant"), 266d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("FirstOperandColumn"), 267d0bc7f060ece77c670794ef60f7052e2ff1847c9Sean Callanan AsmWriter->getValueAsInt("OperandSpacing"))); 2685765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 269bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Get the instruction numbering. 270f65027842e82027dd6e8020586a299aaa548e355Chris Lattner NumberedInstructions = Target.getInstructionsByEnumValue(); 2719255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2726af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not 2736af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // all machine instructions are necessarily being printed, so there may be 2746af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // target instructions not in this map. 2756af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) 2766af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); 2776af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 2786af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Build an aggregate string, and build a table of offsets into it. 2793200fc9badda8964fac571995bd74a3954977ddcChris Lattner StringToOffsetTable StringTable; 2809255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 281259bda48e2c6b886f707513781f1b76595d4ad0dChris Lattner /// OpcodeInfo - This encodes the index of the string to use for the first 2825561640043666174a1e4d828107702a8992e59f6Chris Lattner /// chunk of the output as well as indices used for operand printing. 2835561640043666174a1e4d828107702a8992e59f6Chris Lattner std::vector<unsigned> OpcodeInfo; 2849255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 2855561640043666174a1e4d828107702a8992e59f6Chris Lattner unsigned MaxStringIdx = 0; 2866af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 2876af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 2886af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner unsigned Idx; 289a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner if (AWI == 0) { 2906af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Something not handled by the asmwriter printer. 2913200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = ~0U; 2929255b8d349768a02b2d139a43984c9b544098122Jim Grosbach } else if (AWI->Operands[0].OperandType != 293a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AsmWriterOperand::isLiteralTextOperand || 294a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AWI->Operands[0].Str.empty()) { 295a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner // Something handled by the asmwriter printer, but with no leading string. 2963200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = StringTable.GetOrAddStringOffset(""); 2976af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } else { 2983200fc9badda8964fac571995bd74a3954977ddcChris Lattner std::string Str = AWI->Operands[0].Str; 2993200fc9badda8964fac571995bd74a3954977ddcChris Lattner UnescapeString(Str); 3003200fc9badda8964fac571995bd74a3954977ddcChris Lattner Idx = StringTable.GetOrAddStringOffset(Str); 3013200fc9badda8964fac571995bd74a3954977ddcChris Lattner MaxStringIdx = std::max(MaxStringIdx, Idx); 3029255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3036af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Nuke the string from the operand list. It is now handled! 3046af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AWI->Operands.erase(AWI->Operands.begin()); 3056af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 3069255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3073200fc9badda8964fac571995bd74a3954977ddcChris Lattner // Bias offset by one since we want 0 as a sentinel. 3083200fc9badda8964fac571995bd74a3954977ddcChris Lattner OpcodeInfo.push_back(Idx+1); 309bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3109255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3115561640043666174a1e4d828107702a8992e59f6Chris Lattner // Figure out how many bits we used for the string index. 3123200fc9badda8964fac571995bd74a3954977ddcChris Lattner unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2); 3139255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 314bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // To reduce code size, we compactify common instructions into a few bits 315bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // in the opcode-indexed table. 316b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner unsigned BitsLeft = 32-AsmStrBits; 317bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 318bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::vector<std::string> > TableDrivenOperandPrinters; 3199255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 320b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner while (1) { 321bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> UniqueOperandCommands; 322bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<unsigned> InstIdxs; 32396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> NumInstOpsHandled; 32496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs, 32596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NumInstOpsHandled); 3269255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 327bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we ran out of operands to print, we're done. 328bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands.empty()) break; 3299255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 330bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 331bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 332bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size()); 3339255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 334bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we don't have enough bits for this operand, don't include it. 335bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (NumBits > BitsLeft) { 336569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner DEBUG(errs() << "Not enough bits to densely encode " << NumBits 337569f121f4ecc53f8ab505c4ccb6e1e77c78e188dChris Lattner << " more bits\n"); 338bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 339bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3409255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 341bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Otherwise, we can include this in the initial lookup table. Add it in. 342bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 343bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i) 344195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner if (InstIdxs[i] != ~0U) 345195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits); 3469255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 347b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remove the info about this operand. 348b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 349b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (AsmWriterInst *Inst = getAsmWriterInstByID(i)) 35096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!Inst->Operands.empty()) { 35196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner unsigned NumOps = NumInstOpsHandled[InstIdxs[i]]; 3520a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner assert(NumOps <= Inst->Operands.size() && 3530a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner "Can't remove this many ops!"); 35496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.erase(Inst->Operands.begin(), 35596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.begin()+NumOps); 35696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 357b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner } 3589255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 359b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remember the handlers for this set of operands. 360bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner TableDrivenOperandPrinters.push_back(UniqueOperandCommands); 361bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 3629255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3639255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3649255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3655561640043666174a1e4d828107702a8992e59f6Chris Lattner O<<" static const unsigned OpInfo[] = {\n"; 366bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 367b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " " << OpcodeInfo[i] << "U,\t// " 3685561640043666174a1e4d828107702a8992e59f6Chris Lattner << NumberedInstructions[i]->TheDef->getName() << "\n"; 3696af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 370bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Add a dummy entry so the array init doesn't end with a comma. 3715561640043666174a1e4d828107702a8992e59f6Chris Lattner O << " 0U\n"; 3726af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " };\n\n"; 3739255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 3746af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Emit the string itself. 3753200fc9badda8964fac571995bd74a3954977ddcChris Lattner O << " const char *AsmStrs = \n"; 3763200fc9badda8964fac571995bd74a3954977ddcChris Lattner StringTable.EmitString(O); 3773200fc9badda8964fac571995bd74a3954977ddcChris Lattner O << ";\n\n"; 3786af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 3794eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng O << " O << \"\\t\";\n\n"; 3804eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng 3816af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " // Emit the opcode for the instruction.\n" 3825561640043666174a1e4d828107702a8992e59f6Chris Lattner << " unsigned Bits = OpInfo[MI->getOpcode()];\n" 38341aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" 3843200fc9badda8964fac571995bd74a3954977ddcChris Lattner << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; 385a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 386bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Output the table driven operand information. 387b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner BitsLeft = 32-AsmStrBits; 388bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) { 389bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> &Commands = TableDrivenOperandPrinters[i]; 390f876668518097413a904537ce9d249953987508cChris Lattner 391bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 392bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 393bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(Commands.size()); 394bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner assert(NumBits <= BitsLeft && "consistency error"); 3959255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 396bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Emit code to extract this field from Bits. 397bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 3989255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 399bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << "\n // Fragment " << i << " encoded into " << NumBits 400e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " bits for " << Commands.size() << " unique commands.\n"; 4019255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 40296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (Commands.size() == 2) { 403e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Emit two possibilitys with if/else. 404e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 405e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 406e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[1] 407e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " } else {\n" 408e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[0] 409e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " }\n\n"; 410168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher } else if (Commands.size() == 1) { 411168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher // Emit a single possibility. 412168705049c55feec88aec65af0aef07fc1376ce6Eric Christopher O << Commands[0] << "\n\n"; 413e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } else { 414e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 415e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 416e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " default: // unreachable.\n"; 4179255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 418e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Print out all the cases. 419e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner for (unsigned i = 0, e = Commands.size(); i != e; ++i) { 420e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " case " << i << ":\n"; 421e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << Commands[i]; 422e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " break;\n"; 423e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } 424e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " }\n\n"; 425bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 426bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 4279255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 428b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Okay, delete instructions with no operand info left. 429bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { 430bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Entire instruction has been emitted? 431bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner AsmWriterInst &Inst = Instructions[i]; 432b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst.Operands.empty()) { 433bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instructions.erase(Instructions.begin()+i); 434b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner --i; --e; 435bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 436bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 437bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 4389255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 439bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Because this is a vector, we want to emit from the end. Reverse all of the 440870c016934bacf43995d89531b166ae095ee3675Chris Lattner // elements in the vector. 441870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::reverse(Instructions.begin(), Instructions.end()); 4429255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4439255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 444700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // Now that we've emitted all of the operand info that fit into 32 bits, emit 445700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // information for those instructions that are left. This is a less dense 446700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // encoding, but we expect the main 32-bit table to handle the majority of 447700676087f338ff8eae3b90d34095df88a7b6c46Chris Lattner // instructions. 448b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner if (!Instructions.empty()) { 449b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner // Find the opcode # of inline asm. 450b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " switch (MI->getOpcode()) {\n"; 451b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner while (!Instructions.empty()) 452b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner EmitInstructions(Instructions, O); 453870c016934bacf43995d89531b166ae095ee3675Chris Lattner 454b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " }\n"; 45541aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner O << " return;\n"; 456b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner } 457c8d060503619d32012167d2427891a85e116f3d2David Greene 4580a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner O << "}\n"; 4592e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner} 46005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 46105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 46205af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 46367db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 46405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner Record *AsmWriter = Target.getAsmWriter(); 46505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 466abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const std::vector<CodeGenRegister*> &Registers = 467abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen Target.getRegBank().getRegisters(); 4689255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 469f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner StringToOffsetTable StringTable; 47005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner O << 47105af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" 47205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// from the register set description. This returns the assembler name\n" 47305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "/// for the specified register.\n" 47405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner "const char *" << Target.getName() << ClassName 475d95148f073c31924f275a34296da52a7cdefad91Chris Lattner << "::getRegisterName(unsigned RegNo) {\n" 47605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << " assert(RegNo && RegNo < " << (Registers.size()+1) 47705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << " && \"Invalid register number!\");\n" 47805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << "\n" 479f96271afed5504d75a71e9dd9ed89152645604aaChris Lattner << " static const unsigned RegAsmOffset[] = {"; 48005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 481abdbc84b4ed4276ed3def50f554e3ba156325717Jakob Stoklund Olesen const CodeGenRegister &Reg = *Registers[i]; 48205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 48305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner std::string AsmName = Reg.TheDef->getValueAsString("AsmName"); 48405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner if (AsmName.empty()) 48505af2616d0df19638e799d3e7afadea26d96a4baChris Lattner AsmName = Reg.getName(); 4869255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 4879255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 488f96271afed5504d75a71e9dd9ed89152645604aaChris Lattner if ((i % 14) == 0) 489f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << "\n "; 4909255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 491f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << StringTable.GetOrAddStringOffset(AsmName) << ", "; 49205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner } 493f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << "0\n" 49405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << " };\n" 495f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner << "\n"; 4969255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 497f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << " const char *AsmStrs =\n"; 498f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner StringTable.EmitString(O); 499f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << ";\n"; 5009255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 501f6761be50d9fe4beee1a8a9eeedb33e529011f9fChris Lattner O << " return AsmStrs+RegAsmOffset[RegNo-1];\n" 50205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner << "}\n"; 50305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner} 50405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 5050d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattnervoid AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) { 50667db883487fca3472fdde51e931657e22d4d0495Chris Lattner CodeGenTarget Target(Records); 5070d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner Record *AsmWriter = Target.getAsmWriter(); 5080d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 5090d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 510f65027842e82027dd6e8020586a299aaa548e355Chris Lattner const std::vector<const CodeGenInstruction*> &NumberedInstructions = 511f65027842e82027dd6e8020586a299aaa548e355Chris Lattner Target.getInstructionsByEnumValue(); 5129255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5130d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner StringToOffsetTable StringTable; 5140d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << 5150d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"\n\n#ifdef GET_INSTRUCTION_NAME\n" 5160d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"#undef GET_INSTRUCTION_NAME\n\n" 5170d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"/// getInstructionName: This method is automatically generated by tblgen\n" 5180d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"/// from the instruction set description. This returns the enum name of the\n" 5190d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner"/// specified instruction.\n" 5200d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner "const char *" << Target.getName() << ClassName 5210d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "::getInstructionName(unsigned Opcode) {\n" 5220d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " assert(Opcode < " << NumberedInstructions.size() 5230d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " && \"Invalid instruction number!\");\n" 5240d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "\n" 5250d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " static const unsigned InstAsmOffset[] = {"; 5260d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 5270d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner const CodeGenInstruction &Inst = *NumberedInstructions[i]; 5289255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5290d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner std::string AsmName = Inst.TheDef->getName(); 5300d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner if ((i % 14) == 0) 5310d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << "\n "; 5329255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5330d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << StringTable.GetOrAddStringOffset(AsmName) << ", "; 5340d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner } 5350d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << "0\n" 5360d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << " };\n" 5370d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "\n"; 5389255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5390d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << " const char *Strs =\n"; 5400d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner StringTable.EmitString(O); 5410d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << ";\n"; 5429255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 5430d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner O << " return Strs+InstAsmOffset[Opcode];\n" 5440d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner << "}\n\n#endif\n"; 5450d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner} 5460d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 5472cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingnamespace { 5487520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 5492cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling/// SubtargetFeatureInfo - Helper class for storing information on a subtarget 5502cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling/// feature which participates in instruction matching. 5512cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingstruct SubtargetFeatureInfo { 5522cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling /// \brief The predicate record for this feature. 5532cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling const Record *TheDef; 5542cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5552cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling /// \brief An unique index assigned to represent this feature. 5562cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling unsigned Index; 5572cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5582cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling SubtargetFeatureInfo(const Record *D, unsigned Idx) : TheDef(D), Index(Idx) {} 5592cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5602cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling /// \brief The name of the enumerated constant identifying this feature. 5612cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling std::string getEnumName() const { 5622cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling return "Feature_" + TheDef->getName(); 5632cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 5642cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling}; 5652cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5662cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingstruct AsmWriterInfo { 5672cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling /// Map of Predicate records to their subtarget information. 5682cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling std::map<const Record*, SubtargetFeatureInfo*> SubtargetFeatures; 5692cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5702cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling /// getSubtargetFeature - Lookup or create the subtarget feature info for the 5712cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling /// given operand. 5722cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling SubtargetFeatureInfo *getSubtargetFeature(const Record *Def) const { 5732cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!"); 5742cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling std::map<const Record*, SubtargetFeatureInfo*>::const_iterator I = 5752cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling SubtargetFeatures.find(Def); 5762cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling return I == SubtargetFeatures.end() ? 0 : I->second; 5772cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 5782cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5792cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling void addReqFeatures(const std::vector<Record*> &Features) { 5802cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling for (std::vector<Record*>::const_iterator 5812cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling I = Features.begin(), E = Features.end(); I != E; ++I) { 5822cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling const Record *Pred = *I; 5832cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5842cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling // Ignore predicates that are not intended for the assembler. 5852cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling if (!Pred->getValueAsBit("AssemblerMatcherPredicate")) 5862cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling continue; 5872cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5882cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling if (Pred->getName().empty()) 5892cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling throw TGError(Pred->getLoc(), "Predicate has no name!"); 5902cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5912cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling // Don't add the predicate again. 5922cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling if (getSubtargetFeature(Pred)) 5932cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling continue; 5942cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 5952cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling unsigned FeatureNo = SubtargetFeatures.size(); 5962cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling SubtargetFeatures[Pred] = new SubtargetFeatureInfo(Pred, FeatureNo); 5972cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling assert(FeatureNo < 32 && "Too many subtarget features!"); 5982cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 5992cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 6002cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 6012cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling const SubtargetFeatureInfo *getFeatureInfo(const Record *R) { 6022cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling return SubtargetFeatures[R]; 6032cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 6042cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling}; 6052cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 6064962e6143186f6168f5d0ee979bf047651a13124Bill Wendling// IAPrinter - Holds information about an InstAlias. Two InstAliases match if 6074962e6143186f6168f5d0ee979bf047651a13124Bill Wendling// they both have the same conditionals. In which case, we cannot print out the 6084962e6143186f6168f5d0ee979bf047651a13124Bill Wendling// alias for that pattern. 6094962e6143186f6168f5d0ee979bf047651a13124Bill Wendlingclass IAPrinter { 6104962e6143186f6168f5d0ee979bf047651a13124Bill Wendling AsmWriterInfo &AWI; 6114962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::vector<std::string> Conds; 6124962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::map<StringRef, unsigned> OpMap; 6134962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::string Result; 6144962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::string AsmString; 6154962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::vector<Record*> ReqFeatures; 6164962e6143186f6168f5d0ee979bf047651a13124Bill Wendlingpublic: 6174962e6143186f6168f5d0ee979bf047651a13124Bill Wendling IAPrinter(AsmWriterInfo &Info, std::string R, std::string AS) 6184962e6143186f6168f5d0ee979bf047651a13124Bill Wendling : AWI(Info), Result(R), AsmString(AS) {} 6194962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6204962e6143186f6168f5d0ee979bf047651a13124Bill Wendling void addCond(const std::string &C) { Conds.push_back(C); } 6214962e6143186f6168f5d0ee979bf047651a13124Bill Wendling void addReqFeatures(const std::vector<Record*> &Features) { 6224962e6143186f6168f5d0ee979bf047651a13124Bill Wendling AWI.addReqFeatures(Features); 6234962e6143186f6168f5d0ee979bf047651a13124Bill Wendling ReqFeatures = Features; 6244962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6254962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6264962e6143186f6168f5d0ee979bf047651a13124Bill Wendling void addOperand(StringRef Op, unsigned Idx) { OpMap[Op] = Idx; } 6274962e6143186f6168f5d0ee979bf047651a13124Bill Wendling unsigned getOpIndex(StringRef Op) { return OpMap[Op]; } 6284962e6143186f6168f5d0ee979bf047651a13124Bill Wendling bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); } 6294962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 630dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling bool print(raw_ostream &O) { 63144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (Conds.empty() && ReqFeatures.empty()) { 63244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "return true;\n"; 633dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling return false; 63444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 6353ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 63644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "if ("; 6374962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6384962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<std::string>::iterator 6394962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = Conds.begin(), E = Conds.end(); I != E; ++I) { 6404962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (I != Conds.begin()) { 6414962e6143186f6168f5d0ee979bf047651a13124Bill Wendling O << " &&\n"; 64244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(8); 6434962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6443ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 6454962e6143186f6168f5d0ee979bf047651a13124Bill Wendling O << *I; 6464962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6474962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6484962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (!ReqFeatures.empty()) { 64944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (Conds.begin() != Conds.end()) { 6503ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling O << " &&\n"; 65144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(8); 65244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } else { 6533ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling O << "if ("; 65444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 6553ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 6564962e6143186f6168f5d0ee979bf047651a13124Bill Wendling std::string Req; 6574962e6143186f6168f5d0ee979bf047651a13124Bill Wendling raw_string_ostream ReqO(Req); 6584962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6594962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<Record*>::iterator 6604962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = ReqFeatures.begin(), E = ReqFeatures.end(); I != E; ++I) { 6614962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (I != ReqFeatures.begin()) ReqO << " | "; 6624962e6143186f6168f5d0ee979bf047651a13124Bill Wendling ReqO << AWI.getFeatureInfo(*I)->getEnumName(); 6634962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6644962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6654962e6143186f6168f5d0ee979bf047651a13124Bill Wendling O << "(AvailableFeatures & (" << ReqO.str() << ")) == (" 6664962e6143186f6168f5d0ee979bf047651a13124Bill Wendling << ReqO.str() << ')'; 6674962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6684962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 66944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << ") {\n"; 67044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "// " << Result << "\n"; 67144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "AsmString = \"" << AsmString << "\";\n"; 6724962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6734962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::map<StringRef, unsigned>::iterator 6744962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = OpMap.begin(), E = OpMap.end(); I != E; ++I) 675f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O.indent(6) << "OpMap.push_back(std::make_pair(\"" << I->first << "\", " 676f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << I->second << "));\n"; 6774962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 67844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(6) << "break;\n"; 67944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(4) << '}'; 680dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling return !ReqFeatures.empty(); 6814962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6824962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6834962e6143186f6168f5d0ee979bf047651a13124Bill Wendling bool operator==(const IAPrinter &RHS) { 6844962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (Conds.size() != RHS.Conds.size()) 6854962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return false; 6864962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6874962e6143186f6168f5d0ee979bf047651a13124Bill Wendling unsigned Idx = 0; 6884962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<std::string>::iterator 6894962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = Conds.begin(), E = Conds.end(); I != E; ++I) 6904962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (*I != RHS.Conds[Idx++]) 6914962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return false; 6924962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6934962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return true; 6944962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 6954962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 6964962e6143186f6168f5d0ee979bf047651a13124Bill Wendling bool operator()(const IAPrinter &RHS) { 6974962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (Conds.size() < RHS.Conds.size()) 6984962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return true; 6994962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 7004962e6143186f6168f5d0ee979bf047651a13124Bill Wendling unsigned Idx = 0; 7014962e6143186f6168f5d0ee979bf047651a13124Bill Wendling for (std::vector<std::string>::iterator 7024962e6143186f6168f5d0ee979bf047651a13124Bill Wendling I = Conds.begin(), E = Conds.end(); I != E; ++I) 7034962e6143186f6168f5d0ee979bf047651a13124Bill Wendling if (*I != RHS.Conds[Idx++]) 7044962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return *I < RHS.Conds[Idx++]; 7054962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 7064962e6143186f6168f5d0ee979bf047651a13124Bill Wendling return false; 7074962e6143186f6168f5d0ee979bf047651a13124Bill Wendling } 7084962e6143186f6168f5d0ee979bf047651a13124Bill Wendling}; 7094962e6143186f6168f5d0ee979bf047651a13124Bill Wendling 7102cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling} // end anonymous namespace 7112cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7122cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag 7132cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling/// definitions. 7142cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingstatic void EmitSubtargetFeatureFlagEnumeration(AsmWriterInfo &Info, 7152cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling raw_ostream &O) { 7162cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "namespace {\n\n"; 7172cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "// Flags for subtarget features that participate in " 7182cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling << "alias instruction matching.\n"; 7192cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "enum SubtargetFeatureFlag {\n"; 7202cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7212cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling for (std::map<const Record*, SubtargetFeatureInfo*>::const_iterator 7222cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling I = Info.SubtargetFeatures.begin(), 7232cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling E = Info.SubtargetFeatures.end(); I != E; ++I) { 7242cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling SubtargetFeatureInfo &SFI = *I->second; 7252cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << " " << SFI.getEnumName() << " = (1 << " << SFI.Index << "),\n"; 7262cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 7272cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7282cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << " Feature_None = 0\n"; 7292cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "};\n\n"; 73044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "} // end anonymous namespace\n\n"; 7312cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling} 7322cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7332cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling/// EmitComputeAvailableFeatures - Emit the function to compute the list of 7342cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling/// available features given a subtarget. 7352cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingstatic void EmitComputeAvailableFeatures(AsmWriterInfo &Info, 7362cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling Record *AsmWriter, 7372cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling CodeGenTarget &Target, 7382cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling raw_ostream &O) { 7392cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 7402cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7412cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "unsigned " << Target.getName() << ClassName << "::\n" 7422cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling << "ComputeAvailableFeatures(const " << Target.getName() 7432cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling << "Subtarget *Subtarget) const {\n"; 7442cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << " unsigned Features = 0;\n"; 7452cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7462cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling for (std::map<const Record*, SubtargetFeatureInfo*>::const_iterator 7472cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling I = Info.SubtargetFeatures.begin(), 7482cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling E = Info.SubtargetFeatures.end(); I != E; ++I) { 7492cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling SubtargetFeatureInfo &SFI = *I->second; 7502cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << " if (" << SFI.TheDef->getValueAsString("CondString") 7512cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling << ")\n"; 7522cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << " Features |= " << SFI.getEnumName() << ";\n"; 7532cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling } 7542cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 7552cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << " return Features;\n"; 7562cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "}\n\n"; 7572cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling} 7582cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 759f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendlingstatic void EmitGetMapOperandNumber(raw_ostream &O) { 760f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << "static unsigned getMapOperandNumber(" 761f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << "const SmallVectorImpl<std::pair<StringRef, unsigned> > &OpMap,\n"; 762f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " StringRef Name) {\n"; 763f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " for (SmallVectorImpl<std::pair<StringRef, unsigned> >::" 764f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << "const_iterator\n"; 765f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " I = OpMap.begin(), E = OpMap.end(); I != E; ++I)\n"; 766f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " if (I->first == Name)\n"; 767f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " return I->second;\n"; 768f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " assert(false && \"Operand not in map!\");\n"; 769f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " return 0;\n"; 770f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << "}\n\n"; 771f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling} 772f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling 7732cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingvoid AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) { 7742cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling CodeGenTarget Target(Records); 7757520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7767520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Enumerate the register classes. 7777520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const std::vector<CodeGenRegisterClass> &RegisterClasses = 7787520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling Target.getRegisterClasses(); 7797520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7807520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "namespace { // Register classes\n"; 7817520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " enum RegClass {\n"; 7827520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7837520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Emit the register enum value for each RegisterClass. 7847520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { 7857520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling if (I != 0) O << ",\n"; 7867520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " RC_" << RegisterClasses[I].TheDef->getName(); 7877520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 7887520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7897520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "\n };\n"; 7907520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "} // end anonymous namespace\n\n"; 7917520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7927520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Emit a function that returns 'true' if a regsiter is part of a particular 7937520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // register class. I.e., RAX is part of GR64 on X86. 7947520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "static bool regIsInRegisterClass" 7957520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling << "(unsigned RegClass, unsigned Reg) {\n"; 7967520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 7977520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Emit the switch that checks if a register belongs to a particular register 7987520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // class. 7997520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " switch (RegClass) {\n"; 8007520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " default: break;\n"; 8017520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8027520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { 8037520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const CodeGenRegisterClass &RC = RegisterClasses[I]; 8047520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8057520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Give the register class a legal C name if it's anonymous. 8067520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling std::string Name = RC.TheDef->getName(); 8077520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " case RC_" << Name << ":\n"; 8087520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8097520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Emit the register list now. 810ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen unsigned IE = RC.getOrder().size(); 8117520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling if (IE == 1) { 812ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen O << " if (Reg == " << getQualifiedName(RC.getOrder()[0]) << ")\n"; 8137520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " return true;\n"; 8147520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } else { 8157520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " switch (Reg) {\n"; 8167520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " default: break;\n"; 8177520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8187520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling for (unsigned II = 0; II != IE; ++II) { 819ae1920b1efa72c1789d562df4746110d0c2e10bdJakob Stoklund Olesen Record *Reg = RC.getOrder()[II]; 8207520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " case " << getQualifiedName(Reg) << ":\n"; 8217520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 8227520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8237520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " return true;\n"; 8247520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n"; 8257520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 8267520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8277520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " break;\n"; 8287520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 8297520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8307520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n\n"; 8317520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " return false;\n"; 8327520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "}\n\n"; 8332cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling} 8342cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 835740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendlingstatic unsigned CountNumOperands(StringRef AsmString) { 836740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling unsigned NumOps = 0; 837740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling std::pair<StringRef, StringRef> ASM = AsmString.split(' '); 838740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 839740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling while (!ASM.second.empty()) { 840740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling ++NumOps; 841740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling ASM = ASM.second.split(' '); 842740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling } 843740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 844740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling return NumOps; 845740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling} 846740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 847393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendlingstatic unsigned CountResultNumOperands(StringRef AsmString) { 848393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling unsigned NumOps = 0; 849393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling std::pair<StringRef, StringRef> ASM = AsmString.split('\t'); 850393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 851393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling if (!ASM.second.empty()) { 852393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling size_t I = ASM.second.find('{'); 853393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling StringRef Str = ASM.second; 854393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling if (I != StringRef::npos) 855393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling Str = ASM.second.substr(I, ASM.second.find('|', I)); 856393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 857393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling ASM = Str.split(' '); 858393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 859393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling do { 860393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling ++NumOps; 861393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling ASM = ASM.second.split(' '); 862393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling } while (!ASM.second.empty()); 863393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling } 864393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling 865393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling return NumOps; 866393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling} 867740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 8682cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendlingvoid AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { 8692cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling CodeGenTarget Target(Records); 8702cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling Record *AsmWriter = Target.getAsmWriter(); 8712cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 872740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling if (!AsmWriter->getValueAsBit("isMCAsmWriter")) 873740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling return; 874740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 8752cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "\n#ifdef PRINT_ALIAS_INSTR\n"; 8762cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling O << "#undef PRINT_ALIAS_INSTR\n\n"; 8772cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling 8782cf6fc6857a3544e56f1e701e826114906b1cc57Bill Wendling EmitRegIsInRegClass(O); 8797520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8807520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Emit the method that prints the alias instruction. 8817520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 8820d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner 8837520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling std::vector<Record*> AllInstAliases = 8847520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling Records.getAllDerivedDefinitions("InstAlias"); 8857520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8867520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Create a map from the qualified name to a list of potential matches. 8877520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap; 8887520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling for (std::vector<Record*>::iterator 8897520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { 8907520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); 8917520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const Record *R = *I; 892eef965f04bab483a7d2fd46a7d51559197eda5cfBill Wendling if (!R->getValueAsBit("EmitAlias")) 893eef965f04bab483a7d2fd46a7d51559197eda5cfBill Wendling continue; // We were told not to emit the alias, but to emit the aliasee. 8947520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const DagInit *DI = R->getValueAsDag("ResultInst"); 8957520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling const DefInit *Op = dynamic_cast<const DefInit*>(DI->getOperator()); 8967520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling AliasMap[getQualifiedName(Op->getDef())].push_back(Alias); 8977520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 8987520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 8993ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling // A map of which conditions need to be met for each instruction operand 9003ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling // before it can be matched to the mnemonic. 9013ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap; 9023ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling AsmWriterInfo AWI; 9033ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9043ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator 9053ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { 9063ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::vector<CodeGenInstAlias*> &Aliases = I->second; 9073ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9083ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling for (std::vector<CodeGenInstAlias*>::iterator 9093ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) { 9103ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling const CodeGenInstAlias *CGA = *II; 911740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling unsigned LastOpNo = CGA->ResultInstOperandIndex.size(); 912393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling unsigned NumResultOps = 913393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling CountResultNumOperands(CGA->ResultInst->AsmString); 914740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 915740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling // Don't emit the alias if it has more operands than what it's aliasing. 916393c4047c05b6d7b5851d339e51bb2cc35f630c2Bill Wendling if (NumResultOps < CountNumOperands(CGA->AsmString)) 917740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling continue; 918740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling 9193ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAPrinter *IAP = new IAPrinter(AWI, CGA->Result->getAsString(), 9203ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling CGA->AsmString); 9213ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addReqFeatures(CGA->TheDef->getValueAsListOfDefs("Predicates")); 9223ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9233ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::string Cond; 9243ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo); 9253ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 9263ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9273ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling std::map<StringRef, unsigned> OpMap; 9283ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling bool CantHandle = false; 9293ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9303ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling for (unsigned i = 0, e = LastOpNo; i != e; ++i) { 9313ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i]; 9323ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9333ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling switch (RO.Kind) { 9343ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling default: assert(0 && "unexpected InstAlias operand kind"); 9353ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling case CodeGenInstAlias::ResultOperand::K_Record: { 9363ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling const Record *Rec = RO.getRecord(); 9373ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling StringRef ROName = RO.getName(); 9383ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9393ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (Rec->isSubClassOf("RegisterClass")) { 9403ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()"; 9413ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 9423ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9433ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (!IAP->isOpMapped(ROName)) { 9443ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addOperand(ROName, i); 9453ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("regIsInRegisterClass(RC_") + 9463ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling CGA->ResultOperands[i].getRecord()->getName() + 9473ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling ", MI->getOperand(" + llvm::utostr(i) + ").getReg())"; 9483ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 9493ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } else { 9503ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(") + 9513ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(i) + ").getReg() == MI->getOperand(" + 9523ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()"; 9533ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 9543ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9553ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } else { 9563ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling assert(Rec->isSubClassOf("Operand") && "Unexpected operand!"); 957740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling // FIXME: We may need to handle these situations. 9583ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling delete IAP; 9593ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP = 0; 9603ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling CantHandle = true; 9613ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 9623ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9633ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9643ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 9653ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9663ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling case CodeGenInstAlias::ResultOperand::K_Imm: 9673ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(") + 9683ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(i) + ").getImm() == " + 9693ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(CGA->ResultOperands[i].getImm()); 9703ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 9713ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 9723ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling case CodeGenInstAlias::ResultOperand::K_Reg: 9733ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling Cond = std::string("MI->getOperand(") + 9743ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling llvm::utostr(i) + ").getReg() == " + Target.getName() + 9753ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling "::" + CGA->ResultOperands[i].getRegister()->getName(); 9763ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAP->addCond(Cond); 9773ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling break; 9783ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9793ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9803ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (!IAP) break; 9813ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9823ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9833ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling if (CantHandle) continue; 9843ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling IAPrinterMap[I->first].push_back(IAP); 9853ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9863ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling } 9873ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 9883ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling EmitSubtargetFeatureFlagEnumeration(AWI, O); 9893ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling EmitComputeAvailableFeatures(AWI, AsmWriter, Target, O); 9903ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 991f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling std::string Header; 992f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling raw_string_ostream HeaderO(Header); 993f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling 994f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling HeaderO << "bool " << Target.getName() << ClassName 995740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling << "::printAliasInstr(const MCInst" 996f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling << " *MI, raw_ostream &OS) {\n"; 9973ce1b7d514d2898516106c8b2b843ae9386607ceBill Wendling 99844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling std::string Cases; 99944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling raw_string_ostream CasesO(Cases); 1000dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling bool NeedAvailableFeatures = false; 100144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling 100244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::map<std::string, std::vector<IAPrinter*> >::iterator 100344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) { 100444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling std::vector<IAPrinter*> &IAPs = I->second; 100544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling std::vector<IAPrinter*> UniqueIAPs; 100644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling 100744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::vector<IAPrinter*>::iterator 100844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling II = IAPs.begin(), IE = IAPs.end(); II != IE; ++II) { 100944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IAPrinter *LHS = *II; 101044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling bool IsDup = false; 101144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::vector<IAPrinter*>::iterator 101244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling III = IAPs.begin(), IIE = IAPs.end(); III != IIE; ++III) { 101344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IAPrinter *RHS = *III; 101444dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (LHS != RHS && *LHS == *RHS) { 101544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IsDup = true; 10167520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling break; 10177520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 10187520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 10197520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 102044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (!IsDup) UniqueIAPs.push_back(LHS); 102144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 10227520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 102344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling if (UniqueIAPs.empty()) continue; 10247520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 102544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling CasesO.indent(2) << "case " << I->first << ":\n"; 10267520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 102744dcfd36253570ccd5f00189eb918604473135e0Bill Wendling for (std::vector<IAPrinter*>::iterator 102844dcfd36253570ccd5f00189eb918604473135e0Bill Wendling II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) { 102944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling IAPrinter *IAP = *II; 103044dcfd36253570ccd5f00189eb918604473135e0Bill Wendling CasesO.indent(4); 1031dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling NeedAvailableFeatures |= IAP->print(CasesO); 103244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling CasesO << '\n'; 10337520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 10347520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 1035721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher CasesO.indent(4) << "return false;\n"; 103644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling } 10377520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 1038740e5b3586a474f1cea371cf6f652850e5420b90Bill Wendling if (CasesO.str().empty()) { 1039f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << HeaderO.str(); 1040721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher O << " return false;\n"; 104144dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "}\n\n"; 104244dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << "#endif // PRINT_ALIAS_INSTR\n"; 104344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling return; 10447520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling } 10457520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 1046f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling EmitGetMapOperandNumber(O); 1047f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling 1048f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << HeaderO.str(); 104944dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(2) << "StringRef AsmString;\n"; 1050f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O.indent(2) << "SmallVector<std::pair<StringRef, unsigned>, 4> OpMap;\n"; 1051dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling if (NeedAvailableFeatures) 1052dd099e1e5519d718b572ff2b42b2a3581b66b5ddBill Wendling O.indent(2) << "unsigned AvailableFeatures = getAvailableFeatures();\n\n"; 105344dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(2) << "switch (MI->getOpcode()) {\n"; 1054721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher O.indent(2) << "default: return false;\n"; 105544dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O << CasesO.str(); 105644dcfd36253570ccd5f00189eb918604473135e0Bill Wendling O.indent(2) << "}\n\n"; 10577520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 10587520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // Code that prints the alias, replacing the operands with the ones from the 10597520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling // MCInst. 10607520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n"; 10617520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " OS << '\\t' << ASM.first;\n"; 10627520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 10637520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " if (!ASM.second.empty()) {\n"; 10647520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " OS << '\\t';\n"; 10657520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " for (StringRef::iterator\n"; 10667520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n"; 10677520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " if (*I == '$') {\n"; 10687520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " StringRef::iterator Start = ++I;\n"; 10697520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " while (I != E &&\n"; 10707520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " ((*I >= 'a' && *I <= 'z') ||\n"; 10717520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " (*I >= 'A' && *I <= 'Z') ||\n"; 10727520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " (*I >= '0' && *I <= '9') ||\n"; 10737520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " *I == '_'))\n"; 10747520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " ++I;\n"; 10757520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " StringRef Name(Start, I - Start);\n"; 1076f415d8b64687d4db7e1986b74e9da6cae72c0fd1Bill Wendling O << " printOperand(MI, getMapOperandNumber(OpMap, Name), OS);\n"; 10777520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " } else {\n"; 10787520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " OS << *I++;\n"; 10797520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n"; 10807520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n"; 10817520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << " }\n\n"; 10827520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 1083721ef66d17978a7474bc2bde5a0ce2996615a7ceEric Christopher O << " return true;\n"; 10847520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "}\n\n"; 10857520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling 10867520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling O << "#endif // PRINT_ALIAS_INSTR\n"; 10877520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling} 108805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 108905af2616d0df19638e799d3e7afadea26d96a4baChris Lattnervoid AsmWriterEmitter::run(raw_ostream &O) { 109005af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitSourceFileHeader("Assembly Writer Source Fragment", O); 10919255b8d349768a02b2d139a43984c9b544098122Jim Grosbach 109205af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitPrintInstruction(O); 109305af2616d0df19638e799d3e7afadea26d96a4baChris Lattner EmitGetRegisterName(O); 10940d7b0aa76036abc3118d148fbf02ad287bc7be6cChris Lattner EmitGetInstructionName(O); 10957520e3a2b54aee466b458675542db692a7f31ac1Bill Wendling EmitPrintAliasInstruction(O); 109605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner} 109705af2616d0df19638e799d3e7afadea26d96a4baChris Lattner 1098