AsmWriterEmitter.cpp revision 41aefdcdd1c1631041834d53ffada106a5cfaf02
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" 162e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "CodeGenTarget.h" 17175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner#include "Record.h" 186af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner#include "llvm/ADT/StringExtras.h" 19bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/Debug.h" 20bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner#include "llvm/Support/MathExtras.h" 21615ed993e115f8bc97ff0678aa861629fec93880Jeff Cohen#include <algorithm> 22c8d060503619d32012167d2427891a85e116f3d2David Greene#include <sstream> 231a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar#include <iostream> 242e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnerusing namespace llvm; 252e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 26076efa771aa634801202f7b8189e33ee79dfc4edChris Lattnerstatic bool isIdentChar(char C) { 27076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner return (C >= 'a' && C <= 'z') || 28076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner (C >= 'A' && C <= 'Z') || 29076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner (C >= '0' && C <= '9') || 30076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner C == '_'; 31076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner} 32076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner 33ad8c531e202adfc812aeabaaf87616ba27f02339Chris Lattner// This should be an anon namespace, this works around a GCC warning. 34ad8c531e202adfc812aeabaaf87616ba27f02339Chris Lattnernamespace llvm { 35b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner struct AsmWriterOperand { 36c8d060503619d32012167d2427891a85e116f3d2David Greene enum OpType { 37bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene // Output this text surrounded by quotes to the asm. 38c8d060503619d32012167d2427891a85e116f3d2David Greene isLiteralTextOperand, 39bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene // This is the name of a routine to call to print the operand. 40c8d060503619d32012167d2427891a85e116f3d2David Greene isMachineInstrOperand, 41bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene // Output this text verbatim to the asm writer. It is code that 42bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene // will output some text to the asm. 43c8d060503619d32012167d2427891a85e116f3d2David Greene isLiteralStatementOperand 44c8d060503619d32012167d2427891a85e116f3d2David Greene } OperandType; 45b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 46b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// Str - For isLiteralTextOperand, this IS the literal text. For 47bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene /// isMachineInstrOperand, this is the PrinterMethodName for the operand.. 48bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene /// For isLiteralStatementOperand, this is the code to insert verbatim 49bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene /// into the asm writer. 50b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string Str; 51b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 52b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// MiOpNo - For isMachineInstrOperand, this is the operand number of the 53b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner /// machine instruction. 54b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner unsigned MIOpNo; 5504cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner 5604cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner /// MiModifier - For isMachineInstrOperand, this is the modifier string for 5704cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner /// an operand, specified with syntax like ${opname:modifier}. 5804cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner std::string MiModifier; 59b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 607caa2d0ffcbb6faa37e280924d3653912cd52301Cedric Venet // To make VS STL happy 61c8d060503619d32012167d2427891a85e116f3d2David Greene AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {} 623bff2df61cbb5e88bc814240bb35c5502b1628d1Cedric Venet 63c8d060503619d32012167d2427891a85e116f3d2David Greene AsmWriterOperand(const std::string &LitStr, 64c8d060503619d32012167d2427891a85e116f3d2David Greene OpType op = isLiteralTextOperand) 65c8d060503619d32012167d2427891a85e116f3d2David Greene : OperandType(op), Str(LitStr) {} 66b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 6704cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner AsmWriterOperand(const std::string &Printer, unsigned OpNo, 68c8d060503619d32012167d2427891a85e116f3d2David Greene const std::string &Modifier, 69c8d060503619d32012167d2427891a85e116f3d2David Greene OpType op = isMachineInstrOperand) 70c8d060503619d32012167d2427891a85e116f3d2David Greene : OperandType(op), Str(Printer), MIOpNo(OpNo), 7104cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner MiModifier(Modifier) {} 72b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 73870c016934bacf43995d89531b166ae095ee3675Chris Lattner bool operator!=(const AsmWriterOperand &Other) const { 74870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (OperandType != Other.OperandType || Str != Other.Str) return true; 75870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (OperandType == isMachineInstrOperand) 7604cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier; 77870c016934bacf43995d89531b166ae095ee3675Chris Lattner return false; 78870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 7938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner bool operator==(const AsmWriterOperand &Other) const { 8038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner return !operator!=(Other); 8138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner } 82bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 83bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner /// getCode - Return the code that prints this operand. 84bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string getCode() const; 85b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner }; 86bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner} 87b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 88bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattnernamespace llvm { 89d41b30def3181bce4bf87e8bde664d15663165d0Jeff Cohen class AsmWriterInst { 90d41b30def3181bce4bf87e8bde664d15663165d0Jeff Cohen public: 91b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::vector<AsmWriterOperand> Operands; 925765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner const CodeGenInstruction *CGI; 933da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 9459e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter); 95870c016934bacf43995d89531b166ae095ee3675Chris Lattner 96f876668518097413a904537ce9d249953987508cChris Lattner /// MatchesAllButOneOp - If this instruction is exactly identical to the 97f876668518097413a904537ce9d249953987508cChris Lattner /// specified instruction except for one differing operand, return the 98f876668518097413a904537ce9d249953987508cChris Lattner /// differing operand number. Otherwise return ~0. 99f876668518097413a904537ce9d249953987508cChris Lattner unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const; 100870c016934bacf43995d89531b166ae095ee3675Chris Lattner 101b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner private: 102b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner void AddLiteralString(const std::string &Str) { 103b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // If the last operand was already a literal text string, append this to 104b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // it, otherwise add a new operand. 105b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (!Operands.empty() && 106b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand) 107b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.back().Str.append(Str); 108b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner else 109b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner Operands.push_back(AsmWriterOperand(Str)); 110b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 111b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner }; 112b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner} 113b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 114b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 115bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattnerstd::string AsmWriterOperand::getCode() const { 1162698cb6811276736a8e892e545609a9048a917feChris Lattner if (OperandType == isLiteralTextOperand) { 1172698cb6811276736a8e892e545609a9048a917feChris Lattner if (Str.size() == 1) 1182698cb6811276736a8e892e545609a9048a917feChris Lattner return "O << '" + Str + "'; "; 119bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner return "O << \"" + Str + "\"; "; 1202698cb6811276736a8e892e545609a9048a917feChris Lattner } 121bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 1222698cb6811276736a8e892e545609a9048a917feChris Lattner if (OperandType == isLiteralStatementOperand) 123c8d060503619d32012167d2427891a85e116f3d2David Greene return Str; 124c8d060503619d32012167d2427891a85e116f3d2David Greene 1251bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner std::string Result = Str + "(MI"; 1261bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner if (MIOpNo != ~0U) 1271bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner Result += ", " + utostr(MIOpNo); 128bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!MiModifier.empty()) 129bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Result += ", \"" + MiModifier + '"'; 130bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner return Result + "); "; 131b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner} 132b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 133b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 134b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// ParseAsmString - Parse the specified Instruction's AsmString into this 135b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// AsmWriterInst. 136b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// 13759e8677b1927e9e1573ce94defc35537dfa7ae64Chris LattnerAsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter) { 1385765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner this->CGI = &CGI; 13959e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner 14059e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner unsigned Variant = AsmWriter->getValueAsInt("Variant"); 14159e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner int FirstOperandColumn = AsmWriter->getValueAsInt("FirstOperandColumn"); 14259e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner int OperandSpacing = AsmWriter->getValueAsInt("OperandSpacing"); 14359e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner 144b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner unsigned CurVariant = ~0U; // ~0 if we are outside a {.|.|.} region, other #. 145b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 14659e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner // This is the number of tabs we've seen if we're doing columnar layout. 14759e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner unsigned CurColumn = 0; 14859e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner 14959e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner 1501cf9d961b2fc35c8ba67f20fd36c2b5fb51c9709Chris Lattner // NOTE: Any extensions to this code need to be mirrored in the 1511cf9d961b2fc35c8ba67f20fd36c2b5fb51c9709Chris Lattner // AsmPrinter::printInlineAsm code that executes as compile time (assuming 1521cf9d961b2fc35c8ba67f20fd36c2b5fb51c9709Chris Lattner // that inline asm strings should also get the new feature)! 153b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner const std::string &AsmString = CGI.AsmString; 154b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type LastEmitted = 0; 155b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner while (LastEmitted != AsmString.size()) { 156b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type DollarPos = 157817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman AsmString.find_first_of("${|}\\", LastEmitted); 158b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (DollarPos == std::string::npos) DollarPos = AsmString.size(); 159b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 160b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // Emit a constant string fragment. 161c8d060503619d32012167d2427891a85e116f3d2David Greene 162b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner if (DollarPos != LastEmitted) { 1637f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner if (CurVariant == Variant || CurVariant == ~0U) { 1647f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner for (; LastEmitted != DollarPos; ++LastEmitted) 1657f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner switch (AsmString[LastEmitted]) { 166c8d060503619d32012167d2427891a85e116f3d2David Greene case '\n': 167c8d060503619d32012167d2427891a85e116f3d2David Greene AddLiteralString("\\n"); 168c8d060503619d32012167d2427891a85e116f3d2David Greene break; 16959e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner case '\t': 17059e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner // If the asm writer is not using a columnar layout, \t is not 17159e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner // magic. 17259e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner if (FirstOperandColumn == -1 || OperandSpacing == -1) { 17359e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner AddLiteralString("\\t"); 174fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer } else { 175fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer // We recognize a tab as an operand delimeter. 176fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer unsigned DestColumn = FirstOperandColumn + 177fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer CurColumn++ * OperandSpacing; 178fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer Operands.push_back( 179fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer AsmWriterOperand("O.PadToColumn(" + 180fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer utostr(DestColumn) + ",1);\n", 181fadf13128f3eb4675068f130cb1f6e0d8a46ac19Benjamin Kramer AsmWriterOperand::isLiteralStatementOperand)); 18259e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner } 183c8d060503619d32012167d2427891a85e116f3d2David Greene break; 184c8d060503619d32012167d2427891a85e116f3d2David Greene case '"': 185c8d060503619d32012167d2427891a85e116f3d2David Greene AddLiteralString("\\\""); 186c8d060503619d32012167d2427891a85e116f3d2David Greene break; 187c8d060503619d32012167d2427891a85e116f3d2David Greene case '\\': 188c8d060503619d32012167d2427891a85e116f3d2David Greene AddLiteralString("\\\\"); 189c8d060503619d32012167d2427891a85e116f3d2David Greene break; 1907f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner default: 1917f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner AddLiteralString(std::string(1, AsmString[LastEmitted])); 1927f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner break; 1937f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner } 1947f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner } else { 1957f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner LastEmitted = DollarPos; 1967f3b28a7867a35ec56a4ed80546e64995d69483eChris Lattner } 197817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman } else if (AsmString[DollarPos] == '\\') { 198817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman if (DollarPos+1 != AsmString.size() && 199817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman (CurVariant == Variant || CurVariant == ~0U)) { 200817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman if (AsmString[DollarPos+1] == 'n') { 201817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman AddLiteralString("\\n"); 202817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman } else if (AsmString[DollarPos+1] == 't') { 20359e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner // If the asm writer is not using a columnar layout, \t is not 20459e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner // magic. 20559e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner if (FirstOperandColumn == -1 || OperandSpacing == -1) { 20659e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner AddLiteralString("\\t"); 20759e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner break; 20859e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner } 20959e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner 21059e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner // We recognize a tab as an operand delimeter. 21159e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner unsigned DestColumn = FirstOperandColumn + 21259e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner CurColumn++ * OperandSpacing; 213bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene Operands.push_back( 21459e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ", 1);\n", 215bef8768bd0576eec0470a80e3039cd5d1fd50c6bDavid Greene AsmWriterOperand::isLiteralStatementOperand)); 21659e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner break; 217817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman } else if (std::string("${|}\\").find(AsmString[DollarPos+1]) 218817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman != std::string::npos) { 219817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman AddLiteralString(std::string(1, AsmString[DollarPos+1])); 220817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman } else { 221817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman throw "Non-supported escaped character found in instruction '" + 222817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman CGI.TheDef->getName() + "'!"; 223817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman } 224817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman LastEmitted = DollarPos+2; 225817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman continue; 226817affccd5aa96e3063c0611c319b0da63fb4d07Nate Begeman } 227b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (AsmString[DollarPos] == '{') { 228b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner if (CurVariant != ~0U) 22900b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen throw "Nested variants found for instruction '" + 2303e3def9c1955ab061575eb9a99aa4297a4de5299Chris Lattner CGI.TheDef->getName() + "'!"; 231b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = DollarPos+1; 232b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner CurVariant = 0; // We are now inside of the variant! 233b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (AsmString[DollarPos] == '|') { 234b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner if (CurVariant == ~0U) 235b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "'|' character found outside of a variant in instruction '" 2363e3def9c1955ab061575eb9a99aa4297a4de5299Chris Lattner + CGI.TheDef->getName() + "'!"; 237b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner ++CurVariant; 238b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner ++LastEmitted; 239b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (AsmString[DollarPos] == '}') { 240b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner if (CurVariant == ~0U) 241b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner throw "'}' character found outside of a variant in instruction '" 2423e3def9c1955ab061575eb9a99aa4297a4de5299Chris Lattner + CGI.TheDef->getName() + "'!"; 243b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner ++LastEmitted; 244b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner CurVariant = ~0U; 245b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else if (DollarPos+1 != AsmString.size() && 246b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString[DollarPos+1] == '$') { 247c8d060503619d32012167d2427891a85e116f3d2David Greene if (CurVariant == Variant || CurVariant == ~0U) { 248b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner AddLiteralString("$"); // "$$" -> $ 249c8d060503619d32012167d2427891a85e116f3d2David Greene } 250b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = DollarPos+2; 251b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } else { 252b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner // Get the name of the variable. 253b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string::size_type VarEnd = DollarPos+1; 254c8d060503619d32012167d2427891a85e116f3d2David Greene 255afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman // handle ${foo}bar as $foo by detecting whether the character following 256afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman // the dollar sign is a curly brace. If so, advance VarEnd and DollarPos 257afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman // so the variable name does not contain the leading curly brace. 258afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman bool hasCurlyBraces = false; 259afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) { 260afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman hasCurlyBraces = true; 261afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman ++DollarPos; 262afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman ++VarEnd; 263afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman } 264afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman 265b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) 266b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner ++VarEnd; 267b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner std::string VarName(AsmString.begin()+DollarPos+1, 268b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner AsmString.begin()+VarEnd); 269afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman 27004cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed 2711bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner // into printOperand. Also support ${:feature}, which is passed into 27216f046a6cee08981084dc4339ceaf76b2e291b4cChris Lattner // PrintSpecial. 27304cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner std::string Modifier; 27404cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner 275afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman // In order to avoid starting the next string at the terminating curly 276afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman // brace, advance the end position past it if we found an opening curly 277afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman // brace. 278afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman if (hasCurlyBraces) { 279afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman if (VarEnd >= AsmString.size()) 280afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman throw "Reached end of string before terminating curly brace in '" 2813e3def9c1955ab061575eb9a99aa4297a4de5299Chris Lattner + CGI.TheDef->getName() + "'"; 28204cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner 28304cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner // Look for a modifier string. 28404cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner if (AsmString[VarEnd] == ':') { 28504cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner ++VarEnd; 28604cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner if (VarEnd >= AsmString.size()) 28704cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner throw "Reached end of string before terminating curly brace in '" 28804cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner + CGI.TheDef->getName() + "'"; 28904cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner 29004cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner unsigned ModifierStart = VarEnd; 29104cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd])) 29204cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner ++VarEnd; 29304cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner Modifier = std::string(AsmString.begin()+ModifierStart, 29404cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner AsmString.begin()+VarEnd); 29504cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner if (Modifier.empty()) 29604cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'"; 29704cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner } 29804cadb3684b14e4aad19f9f29e6c14539866bd56Chris Lattner 299afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman if (AsmString[VarEnd] != '}') 300b03b080a8208b25946bcb96c2a10661b53547ff6Chris Lattner throw "Variable name beginning with '{' did not end with '}' in '" 3013e3def9c1955ab061575eb9a99aa4297a4de5299Chris Lattner + CGI.TheDef->getName() + "'"; 302afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman ++VarEnd; 303afc545616a5a062e6872114f9f1c23070e5e753bNate Begeman } 3041bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner if (VarName.empty() && Modifier.empty()) 30500b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen throw "Stray '$' in '" + CGI.TheDef->getName() + 3063e3def9c1955ab061575eb9a99aa4297a4de5299Chris Lattner "' asm string, maybe you want $$?"; 307b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 3081bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner if (VarName.empty()) { 30916f046a6cee08981084dc4339ceaf76b2e291b4cChris Lattner // Just a modifier, pass this into PrintSpecial. 31016f046a6cee08981084dc4339ceaf76b2e291b4cChris Lattner Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U, Modifier)); 3111bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner } else { 3121bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner // Otherwise, normal operand. 3131bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner unsigned OpNo = CGI.getOperandNamed(VarName); 3141bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo]; 3151bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner 316f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner if (CurVariant == Variant || CurVariant == ~0U) { 317f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner unsigned MIOp = OpInfo.MIOperandNo; 3181bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp, 3191bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner Modifier)); 320f64f9a4b75d07819866bfcf918b922a76d3e1600Chris Lattner } 3211bf6361dfde21fcc0f433c8cf53d5c366225ee3fChris Lattner } 322b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner LastEmitted = VarEnd; 323b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 324b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner } 325ba8dc03935fadb05d4d68f9913543df22487f523Evan Cheng 326c8d060503619d32012167d2427891a85e116f3d2David Greene Operands.push_back( 327c8d060503619d32012167d2427891a85e116f3d2David Greene AsmWriterOperand("EmitComments(*MI);\n", 328c8d060503619d32012167d2427891a85e116f3d2David Greene AsmWriterOperand::isLiteralStatementOperand)); 329ba8dc03935fadb05d4d68f9913543df22487f523Evan Cheng AddLiteralString("\\n"); 330b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner} 331b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 332f876668518097413a904537ce9d249953987508cChris Lattner/// MatchesAllButOneOp - If this instruction is exactly identical to the 333f876668518097413a904537ce9d249953987508cChris Lattner/// specified instruction except for one differing operand, return the differing 334f876668518097413a904537ce9d249953987508cChris Lattner/// operand number. If more than one operand mismatches, return ~1, otherwise 335f876668518097413a904537ce9d249953987508cChris Lattner/// if the instructions are identical return ~0. 336f876668518097413a904537ce9d249953987508cChris Lattnerunsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{ 337f876668518097413a904537ce9d249953987508cChris Lattner if (Operands.size() != Other.Operands.size()) return ~1; 338870c016934bacf43995d89531b166ae095ee3675Chris Lattner 339870c016934bacf43995d89531b166ae095ee3675Chris Lattner unsigned MismatchOperand = ~0U; 340870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = Operands.size(); i != e; ++i) { 341ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov if (Operands[i] != Other.Operands[i]) { 342f876668518097413a904537ce9d249953987508cChris Lattner if (MismatchOperand != ~0U) // Already have one mismatch? 343f876668518097413a904537ce9d249953987508cChris Lattner return ~1U; 3443da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman else 345870c016934bacf43995d89531b166ae095ee3675Chris Lattner MismatchOperand = i; 346ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov } 347870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 348870c016934bacf43995d89531b166ae095ee3675Chris Lattner return MismatchOperand; 349870c016934bacf43995d89531b166ae095ee3675Chris Lattner} 350870c016934bacf43995d89531b166ae095ee3675Chris Lattner 35138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattnerstatic void PrintCases(std::vector<std::pair<std::string, 3521a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar AsmWriterOperand> > &OpsToPrint, raw_ostream &O) { 35338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << " case " << OpsToPrint.back().first << ": "; 35438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterOperand TheOp = OpsToPrint.back().second; 35538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.pop_back(); 35638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 35738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Check to see if any other operands are identical in this list, and if so, 35838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // emit a case label for them. 35938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner for (unsigned i = OpsToPrint.size(); i != 0; --i) 36038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner if (OpsToPrint[i-1].second == TheOp) { 36138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "\n case " << OpsToPrint[i-1].first << ": "; 36238c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner OpsToPrint.erase(OpsToPrint.begin()+i-1); 36338c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner } 36438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 36538c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner // Finally, emit the code. 366bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << TheOp.getCode(); 36738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner O << "break;\n"; 36838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner} 36938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner 370870c016934bacf43995d89531b166ae095ee3675Chris Lattner 371870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// EmitInstructions - Emit the last instruction in the vector and any other 372870c016934bacf43995d89531b166ae095ee3675Chris Lattner/// instructions that are suitably similar to it. 373870c016934bacf43995d89531b166ae095ee3675Chris Lattnerstatic void EmitInstructions(std::vector<AsmWriterInst> &Insts, 3741a55180238dbcf11113f610aea010447e51f595bDaniel Dunbar raw_ostream &O) { 375870c016934bacf43995d89531b166ae095ee3675Chris Lattner AsmWriterInst FirstInst = Insts.back(); 376870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.pop_back(); 377870c016934bacf43995d89531b166ae095ee3675Chris Lattner 378870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::vector<AsmWriterInst> SimilarInsts; 379870c016934bacf43995d89531b166ae095ee3675Chris Lattner unsigned DifferingOperand = ~0; 380870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = Insts.size(); i != 0; --i) { 381f876668518097413a904537ce9d249953987508cChris Lattner unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst); 382f876668518097413a904537ce9d249953987508cChris Lattner if (DiffOp != ~1U) { 383870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (DifferingOperand == ~0U) // First match! 384870c016934bacf43995d89531b166ae095ee3675Chris Lattner DifferingOperand = DiffOp; 385870c016934bacf43995d89531b166ae095ee3675Chris Lattner 386870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this differs in the same operand as the rest of the instructions in 387870c016934bacf43995d89531b166ae095ee3675Chris Lattner // this class, move it to the SimilarInsts list. 388f876668518097413a904537ce9d249953987508cChris Lattner if (DifferingOperand == DiffOp || DiffOp == ~0U) { 389870c016934bacf43995d89531b166ae095ee3675Chris Lattner SimilarInsts.push_back(Insts[i-1]); 390870c016934bacf43995d89531b166ae095ee3675Chris Lattner Insts.erase(Insts.begin()+i-1); 391870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 392870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 393870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 394870c016934bacf43995d89531b166ae095ee3675Chris Lattner 395a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << FirstInst.CGI->Namespace << "::" 396870c016934bacf43995d89531b166ae095ee3675Chris Lattner << FirstInst.CGI->TheDef->getName() << ":\n"; 397870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i) 398a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner O << " case " << SimilarInsts[i].CGI->Namespace << "::" 399870c016934bacf43995d89531b166ae095ee3675Chris Lattner << SimilarInsts[i].CGI->TheDef->getName() << ":\n"; 400870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) { 401870c016934bacf43995d89531b166ae095ee3675Chris Lattner if (i != DifferingOperand) { 402870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If the operand is the same for all instructions, just print it. 403bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << " " << FirstInst.Operands[i].getCode(); 404870c016934bacf43995d89531b166ae095ee3675Chris Lattner } else { 405870c016934bacf43995d89531b166ae095ee3675Chris Lattner // If this is the operand that varies between all of the instructions, 406870c016934bacf43995d89531b166ae095ee3675Chris Lattner // emit a switch for just this operand now. 407870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " switch (MI->getOpcode()) {\n"; 40838c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint; 409a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" + 41038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.CGI->TheDef->getName(), 41138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner FirstInst.Operands[i])); 4123da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 413870c016934bacf43995d89531b166ae095ee3675Chris Lattner for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) { 41438c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AsmWriterInst &AWI = SimilarInsts[si]; 415a1e8a80b96d02c8667021049e7fba9050658f39bChris Lattner OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+ 41638c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.CGI->TheDef->getName(), 41738c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner AWI.Operands[i])); 418870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 41938c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner std::reverse(OpsToPrint.begin(), OpsToPrint.end()); 42038c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner while (!OpsToPrint.empty()) 42138c0751a128c0387c04c0f96a2f092340aaa7545Chris Lattner PrintCases(OpsToPrint, O); 422870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " }"; 423870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 424870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << "\n"; 425870c016934bacf43995d89531b166ae095ee3675Chris Lattner } 426870c016934bacf43995d89531b166ae095ee3675Chris Lattner O << " break;\n"; 427870c016934bacf43995d89531b166ae095ee3675Chris Lattner} 428b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner 429bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattnervoid AsmWriterEmitter:: 430bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris LattnerFindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 43196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstIdxs, 43296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> &InstOpsUsed) const { 433195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner InstIdxs.assign(NumberedInstructions.size(), ~0U); 434bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 435bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // This vector parallels UniqueOperandCommands, keeping track of which 436bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // instructions each case are used for. It is a comma separated string of 437bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // enums. 438bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> InstrsForCase; 439bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.resize(UniqueOperandCommands.size()); 44096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.assign(UniqueOperandCommands.size(), 0); 441bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 442bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 443bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner const AsmWriterInst *Inst = getAsmWriterInstByID(i); 4444406604047423576e36657c7ede266ca42e79642Dan Gohman if (Inst == 0) continue; // PHI, INLINEASM, DBG_LABEL, etc. 445bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 446bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Command; 447b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst->Operands.empty()) 448bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner continue; // Instruction already done. 449191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 450b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner Command = " " + Inst->Operands[0].getCode() + "\n"; 451191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner 452191dd1f1860661f2e0bb99432d10da9b2aff1fc7Chris Lattner // If this is the last operand, emit a return. 4532698cb6811276736a8e892e545609a9048a917feChris Lattner if (Inst->Operands.size() == 1) 45441aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner Command += " return;\n"; 455bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 456bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Check to see if we already have 'Command' in UniqueOperandCommands. 457bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If not, add it. 458bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner bool FoundIt = false; 459bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx) 460bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands[idx] == Command) { 461bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = idx; 462bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += ", "; 463bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase[idx] += Inst->CGI->TheDef->getName(); 464bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner FoundIt = true; 465bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 466bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 467bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!FoundIt) { 468bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstIdxs[i] = UniqueOperandCommands.size(); 469bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands.push_back(Command); 470bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner InstrsForCase.push_back(Inst->CGI->TheDef->getName()); 47196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 47296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // This command matches one operand so far. 47396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed.push_back(1); 47496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 47596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 47696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 47796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // For each entry of UniqueOperandCommands, there is a set of instructions 47896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // that uses it. If the next command of all instructions in the set are 47996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // identical, fold it into the command. 48096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size(); 48196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner CommandIdx != e; ++CommandIdx) { 48296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 48396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (unsigned Op = 1; ; ++Op) { 48496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Scan for the first instruction in the set. 48596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned>::iterator NIT = 48696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx); 48796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (NIT == InstIdxs.end()) break; // No commonality. 48896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 48996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // If this instruction has no more operands, we isn't anything to merge 49096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // into this command. 49196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner const AsmWriterInst *FirstInst = 49296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 49396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!FirstInst || FirstInst->Operands.size() == Op) 49496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 49596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 49696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Otherwise, scan to see if all of the other instructions in this command 49796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // set share the operand. 49896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner bool AllSame = true; 499c8d060503619d32012167d2427891a85e116f3d2David Greene // Keep track of the maximum, number of operands or any 500c8d060503619d32012167d2427891a85e116f3d2David Greene // instruction we see in the group. 501c8d060503619d32012167d2427891a85e116f3d2David Greene size_t MaxSize = FirstInst->Operands.size(); 502c8d060503619d32012167d2427891a85e116f3d2David Greene 50396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx); 50496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT != InstIdxs.end(); 50596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) { 50696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, found another instruction in this command set. If the operand 50796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // matches, we're ok, otherwise bail out. 50896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner const AsmWriterInst *OtherInst = 50996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner getAsmWriterInstByID(NIT-InstIdxs.begin()); 510c8d060503619d32012167d2427891a85e116f3d2David Greene 511c8d060503619d32012167d2427891a85e116f3d2David Greene if (OtherInst && 512c8d060503619d32012167d2427891a85e116f3d2David Greene OtherInst->Operands.size() > FirstInst->Operands.size()) 513c8d060503619d32012167d2427891a85e116f3d2David Greene MaxSize = std::max(MaxSize, OtherInst->Operands.size()); 514c8d060503619d32012167d2427891a85e116f3d2David Greene 51596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!OtherInst || OtherInst->Operands.size() == Op || 51696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner OtherInst->Operands[Op] != FirstInst->Operands[Op]) { 51796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner AllSame = false; 51896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner break; 51996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 52096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 52196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!AllSame) break; 52296c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 52396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // Okay, everything in this command set has the same next operand. Add it 52496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // to UniqueOperandCommands and remember that it was consumed. 52596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n"; 52696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 52796c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner // If this is the last operand, emit a return after the code. 528c8d060503619d32012167d2427891a85e116f3d2David Greene if (FirstInst->Operands.size() == Op+1 && 529c8d060503619d32012167d2427891a85e116f3d2David Greene // Don't early-out too soon. Other instructions in this 530c8d060503619d32012167d2427891a85e116f3d2David Greene // group may have more operands. 531c8d060503619d32012167d2427891a85e116f3d2David Greene FirstInst->Operands.size() == MaxSize) { 53241aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner Command += " return;\n"; 533c8d060503619d32012167d2427891a85e116f3d2David Greene } 53496c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner 53596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner UniqueOperandCommands[CommandIdx] += Command; 53696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner InstOpsUsed[CommandIdx]++; 537bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 538bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 539bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 540bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Prepend some of the instructions each case is used for onto the case val. 541bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) { 542bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::string Instrs = InstrsForCase[i]; 543bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (Instrs.size() > 70) { 544bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs.erase(Instrs.begin()+70, Instrs.end()); 545bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instrs += "..."; 546bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 547bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 548bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (!Instrs.empty()) 549bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands[i] = " // " + Instrs + "\n" + 550bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner UniqueOperandCommands[i]; 551bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 552bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner} 553bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 554bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 555bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 5561a55180238dbcf11113f610aea010447e51f595bDaniel Dunbarvoid AsmWriterEmitter::run(raw_ostream &O) { 5572e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner EmitSourceFileHeader("Assembly Writer Source Fragment", O); 5582e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 5592e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner CodeGenTarget Target; 560175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner Record *AsmWriter = Target.getAsmWriter(); 561953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 562175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner 5632e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner O << 5642e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// printInstruction - This method is automatically generated by tablegen\n" 5652e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// from the instruction set description. This method returns true if the\n" 5662e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// machine instruction was sufficiently described to print it, otherwise\n" 5672e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner "/// it returns false.\n" 56841aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner "void " << Target.getName() << ClassName 569175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner << "::printInstruction(const MachineInstr *MI) {\n"; 5702e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner 5715765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner std::vector<AsmWriterInst> Instructions; 5725765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 5732e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner for (CodeGenTarget::inst_iterator I = Target.inst_begin(), 5742e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner E = Target.inst_end(); I != E; ++I) 5755765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner if (!I->second.AsmString.empty()) 57659e8677b1927e9e1573ce94defc35537dfa7ae64Chris Lattner Instructions.push_back(AsmWriterInst(I->second, AsmWriter)); 5775765dba5ce9f493f063a7caf1106e7db9b6693b6Chris Lattner 578bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Get the instruction numbering. 5790cfcc1e8072af7f3d92bbcdba48da551cccd90beChris Lattner Target.getInstructionsByEnumValue(NumberedInstructions); 5800cfcc1e8072af7f3d92bbcdba48da551cccd90beChris Lattner 5816af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not 5826af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // all machine instructions are necessarily being printed, so there may be 5836af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // target instructions not in this map. 5846af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) 5856af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); 5866af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 5876af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Build an aggregate string, and build a table of offsets into it. 5886af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner std::map<std::string, unsigned> StringOffset; 5896af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner std::string AggregateString; 590259bda48e2c6b886f707513781f1b76595d4ad0dChris Lattner AggregateString.push_back(0); // "\0" 591259bda48e2c6b886f707513781f1b76595d4ad0dChris Lattner AggregateString.push_back(0); // "\0" 5926af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 593259bda48e2c6b886f707513781f1b76595d4ad0dChris Lattner /// OpcodeInfo - This encodes the index of the string to use for the first 5945561640043666174a1e4d828107702a8992e59f6Chris Lattner /// chunk of the output as well as indices used for operand printing. 5955561640043666174a1e4d828107702a8992e59f6Chris Lattner std::vector<unsigned> OpcodeInfo; 596bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 5975561640043666174a1e4d828107702a8992e59f6Chris Lattner unsigned MaxStringIdx = 0; 5986af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 5996af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; 6006af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner unsigned Idx; 601a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner if (AWI == 0) { 6026af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Something not handled by the asmwriter printer. 6036af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner Idx = 0; 604a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner } else if (AWI->Operands[0].OperandType != 605a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AsmWriterOperand::isLiteralTextOperand || 606a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner AWI->Operands[0].Str.empty()) { 607a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner // Something handled by the asmwriter printer, but with no leading string. 608a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner Idx = 1; 6096af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } else { 6106af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner unsigned &Entry = StringOffset[AWI->Operands[0].Str]; 6116af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner if (Entry == 0) { 6126af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Add the string to the aggregate if this is the first time found. 6135561640043666174a1e4d828107702a8992e59f6Chris Lattner MaxStringIdx = Entry = AggregateString.size(); 6146af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner std::string Str = AWI->Operands[0].Str; 6156af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner UnescapeString(Str); 6166af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AggregateString += Str; 6176af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AggregateString += '\0'; 6186af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 6196af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner Idx = Entry; 6206af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 6216af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Nuke the string from the operand list. It is now handled! 6226af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner AWI->Operands.erase(AWI->Operands.begin()); 6236af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 6245561640043666174a1e4d828107702a8992e59f6Chris Lattner OpcodeInfo.push_back(Idx); 625bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 626bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 6275561640043666174a1e4d828107702a8992e59f6Chris Lattner // Figure out how many bits we used for the string index. 62859d28132bcd68f882c526b043380c359ffc465e6Nate Begeman unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+1); 6295561640043666174a1e4d828107702a8992e59f6Chris Lattner 630bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // To reduce code size, we compactify common instructions into a few bits 631bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // in the opcode-indexed table. 632b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner unsigned BitsLeft = 32-AsmStrBits; 633bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 634bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::vector<std::string> > TableDrivenOperandPrinters; 635bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 636b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner bool isFirst = true; 637b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner while (1) { 638bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> UniqueOperandCommands; 639bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 640a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner // For the first operand check, add a default value for instructions with 641a6dc9fb745962564fac3b18da28736b2e094c417Chris Lattner // just opcode strings to use. 642b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (isFirst) { 64341aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner UniqueOperandCommands.push_back(" return;\n"); 644b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner isFirst = false; 645b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner } 646c8d060503619d32012167d2427891a85e116f3d2David Greene 647bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<unsigned> InstIdxs; 64896c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner std::vector<unsigned> NumInstOpsHandled; 64996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs, 65096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner NumInstOpsHandled); 651bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 652bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we ran out of operands to print, we're done. 653bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (UniqueOperandCommands.empty()) break; 654bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 655bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 656bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 657bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size()); 658bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 659bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // If we don't have enough bits for this operand, don't include it. 660bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner if (NumBits > BitsLeft) { 661f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling DOUT << "Not enough bits to densely encode " << NumBits 662f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling << " more bits\n"; 663bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner break; 664bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 665bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 666bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Otherwise, we can include this in the initial lookup table. Add it in. 667bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 668bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i) 669195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner if (InstIdxs[i] != ~0U) 670195bb4a7b0de2bb76ae064a5ab8776094d4fccbbChris Lattner OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits); 671bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 672b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remove the info about this operand. 673b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 674b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (AsmWriterInst *Inst = getAsmWriterInstByID(i)) 67596c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (!Inst->Operands.empty()) { 67696c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner unsigned NumOps = NumInstOpsHandled[InstIdxs[i]]; 6770a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner assert(NumOps <= Inst->Operands.size() && 6780a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner "Can't remove this many ops!"); 67996c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.erase(Inst->Operands.begin(), 68096c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner Inst->Operands.begin()+NumOps); 68196c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner } 682b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner } 683b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner 684b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Remember the handlers for this set of operands. 685bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner TableDrivenOperandPrinters.push_back(UniqueOperandCommands); 686bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 687bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 688bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 689bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 6905561640043666174a1e4d828107702a8992e59f6Chris Lattner O<<" static const unsigned OpInfo[] = {\n"; 691bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { 692b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " " << OpcodeInfo[i] << "U,\t// " 6935561640043666174a1e4d828107702a8992e59f6Chris Lattner << NumberedInstructions[i]->TheDef->getName() << "\n"; 6946af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 695bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Add a dummy entry so the array init doesn't end with a comma. 6965561640043666174a1e4d828107702a8992e59f6Chris Lattner O << " 0U\n"; 6976af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " };\n\n"; 6986af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 6996af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Emit the string itself. 7006af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " const char *AsmStrs = \n \""; 7016af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner unsigned CharsPrinted = 0; 7026af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner EscapeString(AggregateString); 7036af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) { 7046af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner if (CharsPrinted > 70) { 7056af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << "\"\n \""; 7066af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner CharsPrinted = 0; 7076af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner } 7086af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << AggregateString[i]; 7096af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner ++CharsPrinted; 7106af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 7116af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner // Print escape sequences all together. 7126af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner if (AggregateString[i] == '\\') { 7136af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner assert(i+1 < AggregateString.size() && "Incomplete escape sequence!"); 7146af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner if (isdigit(AggregateString[i+1])) { 7156af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner assert(isdigit(AggregateString[i+2]) && isdigit(AggregateString[i+3]) && 7166af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner "Expected 3 digit octal escape!"); 7176af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << AggregateString[++i]; 7186af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << AggregateString[++i]; 7196af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << AggregateString[++i]; 7206af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner CharsPrinted += 3; 721f876668518097413a904537ce9d249953987508cChris Lattner } else { 7226af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << AggregateString[++i]; 7236af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner ++CharsPrinted; 724f876668518097413a904537ce9d249953987508cChris Lattner } 725f876668518097413a904537ce9d249953987508cChris Lattner } 726f876668518097413a904537ce9d249953987508cChris Lattner } 7276af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << "\";\n\n"; 7286af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner 729cd76240f3d0f6c5f8c80e4762a8fe3a4de22e059Argyrios Kyrtzidis O << " processDebugLoc(MI->getDebugLoc());\n\n"; 730cb819f13d785ff6efcacfbd7d0fa9f3f67e5494dBill Wendling 7315b842c369097b22e0abca58bfc49e63919b28a58Chris Lattner O << "\n#ifndef NO_ASM_WRITER_BOILERPLATE\n"; 7325b842c369097b22e0abca58bfc49e63919b28a58Chris Lattner 733bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << " if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n" 7344eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng << " O << \"\\t\";\n" 735bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner << " printInlineAsm(MI);\n" 73641aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " return;\n" 7374406604047423576e36657c7ede266ca42e79642Dan Gohman << " } else if (MI->isLabel()) {\n" 738a683f9ba1356e92a5e7243d9f80fe8a8b6f737c8Jim Laskey << " printLabel(MI);\n" 73941aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " return;\n" 740a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng << " } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) {\n" 741a844bdeab31ef04221e7ef59a8467893584cc14dEvan Cheng << " printDeclare(MI);\n" 74241aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " return;\n" 743da47e6e0d003c873da960361549e57ee4617c301Evan Cheng << " } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {\n" 744da47e6e0d003c873da960361549e57ee4617c301Evan Cheng << " printImplicitDef(MI);\n" 74541aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " return;\n" 746bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner << " }\n\n"; 7475b842c369097b22e0abca58bfc49e63919b28a58Chris Lattner 7485b842c369097b22e0abca58bfc49e63919b28a58Chris Lattner O << "\n#endif\n"; 7495b842c369097b22e0abca58bfc49e63919b28a58Chris Lattner 7504eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng O << " O << \"\\t\";\n\n"; 7514eecdeb3faf5df864790175da5d58301b751ec11Evan Cheng 7526af022f255257bee7c6d6903ff4caa2217d51502Chris Lattner O << " // Emit the opcode for the instruction.\n" 7535561640043666174a1e4d828107702a8992e59f6Chris Lattner << " unsigned Bits = OpInfo[MI->getOpcode()];\n" 75441aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" 755a5bb59f85613e8ce481351803e7388f5ab466e72David Greene << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ");\n\n"; 756a5bb59f85613e8ce481351803e7388f5ab466e72David Greene 757bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Output the table driven operand information. 758b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner BitsLeft = 32-AsmStrBits; 759bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) { 760bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner std::vector<std::string> &Commands = TableDrivenOperandPrinters[i]; 761f876668518097413a904537ce9d249953987508cChris Lattner 762bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Compute the number of bits we need to represent these cases, this is 763bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // ceil(log2(numentries)). 764bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner unsigned NumBits = Log2_32_Ceil(Commands.size()); 765bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner assert(NumBits <= BitsLeft && "consistency error"); 766bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 767bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Emit code to extract this field from Bits. 768bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner BitsLeft -= NumBits; 769bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 770bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner O << "\n // Fragment " << i << " encoded into " << NumBits 771e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " bits for " << Commands.size() << " unique commands.\n"; 772bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 77396c1ade5c3927cb0e835af721cbf37f9605cc678Chris Lattner if (Commands.size() == 2) { 774e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Emit two possibilitys with if/else. 775e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 776e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 777e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[1] 778e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " } else {\n" 779e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << Commands[0] 780e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " }\n\n"; 781e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } else { 782e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & " 783e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << ((1 << NumBits)-1) << ") {\n" 784e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner << " default: // unreachable.\n"; 785e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner 786e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner // Print out all the cases. 787e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner for (unsigned i = 0, e = Commands.size(); i != e; ++i) { 788e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " case " << i << ":\n"; 789e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << Commands[i]; 790e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " break;\n"; 791e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner } 792e7a589df09ed4d1f0853fb586609b00357a34ac2Chris Lattner O << " }\n\n"; 793bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 794bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 795bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 796b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner // Okay, delete instructions with no operand info left. 797bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner for (unsigned i = 0, e = Instructions.size(); i != e; ++i) { 798bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Entire instruction has been emitted? 799bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner AsmWriterInst &Inst = Instructions[i]; 800b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner if (Inst.Operands.empty()) { 801bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner Instructions.erase(Instructions.begin()+i); 802b84628679ad7240a63d267fc6388efbc1e91f588Chris Lattner --i; --e; 803bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 804bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner } 805bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 806bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 807bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner // Because this is a vector, we want to emit from the end. Reverse all of the 808870c016934bacf43995d89531b166ae095ee3675Chris Lattner // elements in the vector. 809870c016934bacf43995d89531b166ae095ee3675Chris Lattner std::reverse(Instructions.begin(), Instructions.end()); 810bdff5f95b9cda9a6d24104201fa53204bd0c5a75Chris Lattner 811b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner if (!Instructions.empty()) { 812b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner // Find the opcode # of inline asm. 813b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " switch (MI->getOpcode()) {\n"; 814b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner while (!Instructions.empty()) 815b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner EmitInstructions(Instructions, O); 816870c016934bacf43995d89531b166ae095ee3675Chris Lattner 817b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner O << " }\n"; 81841aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner O << " return;\n"; 819b51ecd4dd93b8eccf2cba3d541cff0f7cdbf7e1cChris Lattner } 820c8d060503619d32012167d2427891a85e116f3d2David Greene 82141aefdcdd1c1631041834d53ffada106a5cfaf02Chris Lattner O << " return;\n"; 8220a012128574c93d5b85adffd14eb4b07883fba4cChris Lattner O << "}\n"; 8232e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner} 824