1From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 2From: mephi42 <mephi42@gmail.com> 3Date: Tue, 7 Aug 2018 20:00:08 +0200 4Subject: [PATCH 5/7] capstone: generate *GenAsmWriter.inc 5 6--- 7 utils/TableGen/AsmWriterEmitter.cpp | 89 +++++++++++++++++++++++++++-- 8 utils/TableGen/AsmWriterInst.cpp | 4 ++ 9 2 files changed, 87 insertions(+), 6 deletions(-) 10 11diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp 12index 3c4c9c8e5c6..133800d217c 100644 13--- a/utils/TableGen/AsmWriterEmitter.cpp 14+++ b/utils/TableGen/AsmWriterEmitter.cpp 15@@ -272,16 +272,22 @@ static void UnescapeString(std::string &Str) { 16 /// clearing the Instructions vector. 17 void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 18 Record *AsmWriter = Target.getAsmWriter(); 19+#ifndef CAPSTONE 20 StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 21+#endif 22 bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); 23 24 O << 25 "/// printInstruction - This method is automatically generated by tablegen\n" 26 "/// from the instruction set description.\n" 27+#ifdef CAPSTONE 28+ "static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{\n"; 29+#else 30 "void " << Target.getName() << ClassName 31 << "::printInstruction(const MCInst *MI, " 32 << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") 33 << "raw_ostream &O) {\n"; 34+#endif 35 36 // Build an aggregate string, and build a table of offsets into it. 37 SequenceToOffsetTable<std::string> StringTable; 38@@ -379,9 +385,16 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 39 } 40 41 // Emit the string table itself. 42+#ifdef CAPSTONE 43+ O << "#ifndef CAPSTONE_DIET\n"; 44+#endif 45 O << " static const char AsmStrs[] = {\n"; 46 StringTable.emit(O, printChar); 47- O << " };\n\n"; 48+ O << " };\n" 49+#ifdef CAPSTONE 50+ << "#endif\n" 51+#endif 52+ << "\n"; 53 54 // Emit the lookup tables in pieces to minimize wasted bytes. 55 unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8; 56@@ -409,21 +422,45 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 57 // If the total bits is more than 32-bits we need to use a 64-bit type. 58 if (BitsLeft < (OpcodeInfoBits - 32)) 59 BitsOS << "(uint64_t)"; 60- BitsOS << "OpInfo" << Table << "[MI->getOpcode()] << " << Shift << ";\n"; 61+ BitsOS << "OpInfo" << Table << "[" 62+#ifdef CAPSTONE 63+ << "MCInst_getOpcode(MI)" 64+#else 65+ << "MI->getOpcode()" 66+#endif 67+ << "] << " << Shift << ";\n"; 68 // Prepare the shift for the next iteration and increment the table count. 69 Shift += TableSize; 70 ++Table; 71 } 72 73 // Emit the initial tab character. 74+#ifndef CAPSTONE 75 O << " O << \"\\t\";\n\n"; 76+#endif 77 78 O << " // Emit the opcode for the instruction.\n"; 79 O << BitsString; 80 81 // Emit the starting string. 82- O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" 83- << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; 84+ O << " " 85+#ifdef CAPSTONE 86+ << "// " 87+#endif 88+ << "assert(Bits != 0 && \"Cannot print this instruction.\");\n" 89+#ifdef CAPSTONE 90+ << "#ifndef CAPSTONE_DIET\n" 91+ << " SStream_concat0(O, " 92+#else 93+ << " O << " 94+#endif 95+ << "AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1" 96+#ifdef CAPSTONE 97+ << ");\n" 98+ << "#endif\n\n"; 99+#else 100+ << ");\n\n"; 101+#endif 102 103 // Output the table driven operand information. 104 BitsLeft = OpcodeInfoBits-AsmStrBits; 105@@ -455,7 +492,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { 106 O << " switch ((Bits >> " 107 << (OpcodeInfoBits-BitsLeft) << ") & " 108 << ((1 << NumBits)-1) << ") {\n" 109- << " default: llvm_unreachable(\"Invalid command number.\");\n"; 110+ << " default: " 111+#ifdef CAPSTONE 112+ << "// " 113+#endif 114+ << "llvm_unreachable(\"Invalid command number.\");\n"; 115 116 // Print out all the cases. 117 for (unsigned j = 0, e = Commands.size(); j != e; ++j) { 118@@ -536,6 +577,9 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, 119 } 120 121 StringTable.layout(); 122+#ifdef CAPSTONE 123+ O << "#ifndef CAPSTONE_DIET\n"; 124+#endif 125 O << " static const char AsmStrs" << AltName << "[] = {\n"; 126 StringTable.emit(O, printChar); 127 O << " };\n\n"; 128@@ -552,8 +596,10 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, 129 } 130 131 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 132+#ifndef CAPSTONE 133 Record *AsmWriter = Target.getAsmWriter(); 134 StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); 135+#endif 136 const auto &Registers = Target.getRegBank().getRegisters(); 137 const std::vector<Record*> &AltNameIndices = Target.getRegAltNameIndices(); 138 bool hasAltNames = AltNameIndices.size() > 1; 139@@ -563,12 +609,20 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 140 "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" 141 "/// from the register set description. This returns the assembler name\n" 142 "/// for the specified register.\n" 143+#ifdef CAPSTONE 144+ "static const char *getRegisterName(unsigned RegNo)\n{\n"; 145+#else 146 "const char *" << Target.getName() << ClassName << "::"; 147 if (hasAltNames) 148 O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; 149 else 150 O << "getRegisterName(unsigned RegNo) {\n"; 151- O << " assert(RegNo && RegNo < " << (Registers.size()+1) 152+#endif 153+ O << " " 154+#ifdef CAPSTONE 155+ << "// " 156+#endif 157+ << "assert(RegNo && RegNo < " << (Registers.size()+1) 158 << " && \"Invalid register number!\");\n" 159 << "\n"; 160 161@@ -595,10 +649,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { 162 } 163 O << " }\n"; 164 } else { 165+#ifdef CAPSTONE 166+ O << " //int i;\n" 167+ << " //for (i = 0; i < sizeof(RegAsmOffset); i++)\n" 168+ << " // printf(\"%s = %u\\n\", AsmStrs+RegAsmOffset[i], i + 1);\n" 169+ << " //printf(\"*************************\\n\");\n" 170+#else 171 O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" 172 << " \"Invalid alt name index for register!\");\n" 173+#endif 174 << " return AsmStrs+RegAsmOffset[RegNo-1];\n"; 175 } 176+#ifdef CAPSTONE 177+ O << "#else\n" 178+ << " return NULL;\n" 179+ << "#endif\n"; 180+#endif 181 O << "}\n"; 182 } 183 184@@ -1135,9 +1201,20 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { 185 } 186 187 void AsmWriterEmitter::run(raw_ostream &O) { 188+#ifdef CAPSTONE 189+ O << "/* Capstone Disassembly Engine */\n" 190+ "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n" 191+ "\n" 192+ "#include <stdio.h>\t// debug\n" 193+ "#include <capstone/platform.h>\n" 194+ "\n" 195+ "\n"; 196+#endif 197 EmitPrintInstruction(O); 198 EmitGetRegisterName(O); 199+#ifndef CAPSTONE 200 EmitPrintAliasInstruction(O); 201+#endif 202 } 203 204 namespace llvm { 205diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp 206index 2c19e5d663d..6fa751e50df 100644 207--- a/utils/TableGen/AsmWriterInst.cpp 208+++ b/utils/TableGen/AsmWriterInst.cpp 209@@ -28,9 +28,13 @@ static bool isIdentChar(char C) { 210 211 std::string AsmWriterOperand::getCode(bool PassSubtarget) const { 212 if (OperandType == isLiteralTextOperand) { 213+#ifdef CAPSTONE 214+ return "SStream_concat0(O, \"" + Str + "\");"; 215+#else 216 if (Str.size() == 1) 217 return "O << '" + Str + "';"; 218 return "O << \"" + Str + "\";"; 219+#endif 220 } 221 222 if (OperandType == isLiteralStatementOperand) 223-- 2242.19.1 225 226