| From 5569e48b9cb34a33910e1e850fbfabc999f016a2 Mon Sep 17 00:00:00 2001 |
| From: mephi42 <mephi42@gmail.com> |
| Date: Tue, 7 Aug 2018 20:00:08 +0200 |
| Subject: [PATCH 5/7] capstone: generate *GenAsmWriter.inc |
| |
| --- |
| utils/TableGen/AsmWriterEmitter.cpp | 89 +++++++++++++++++++++++++++-- |
| utils/TableGen/AsmWriterInst.cpp | 4 ++ |
| 2 files changed, 87 insertions(+), 6 deletions(-) |
| |
| diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp |
| index 3c4c9c8e5c6..133800d217c 100644 |
| --- a/utils/TableGen/AsmWriterEmitter.cpp |
| +++ b/utils/TableGen/AsmWriterEmitter.cpp |
| @@ -272,16 +272,22 @@ static void UnescapeString(std::string &Str) { |
| /// clearing the Instructions vector. |
| void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { |
| Record *AsmWriter = Target.getAsmWriter(); |
| +#ifndef CAPSTONE |
| StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); |
| +#endif |
| bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); |
| |
| O << |
| "/// printInstruction - This method is automatically generated by tablegen\n" |
| "/// from the instruction set description.\n" |
| +#ifdef CAPSTONE |
| + "static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)\n{\n"; |
| +#else |
| "void " << Target.getName() << ClassName |
| << "::printInstruction(const MCInst *MI, " |
| << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") |
| << "raw_ostream &O) {\n"; |
| +#endif |
| |
| // Build an aggregate string, and build a table of offsets into it. |
| SequenceToOffsetTable<std::string> StringTable; |
| @@ -379,9 +385,16 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { |
| } |
| |
| // Emit the string table itself. |
| +#ifdef CAPSTONE |
| + O << "#ifndef CAPSTONE_DIET\n"; |
| +#endif |
| O << " static const char AsmStrs[] = {\n"; |
| StringTable.emit(O, printChar); |
| - O << " };\n\n"; |
| + O << " };\n" |
| +#ifdef CAPSTONE |
| + << "#endif\n" |
| +#endif |
| + << "\n"; |
| |
| // Emit the lookup tables in pieces to minimize wasted bytes. |
| unsigned BytesNeeded = ((OpcodeInfoBits - BitsLeft) + 7) / 8; |
| @@ -409,21 +422,45 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { |
| // If the total bits is more than 32-bits we need to use a 64-bit type. |
| if (BitsLeft < (OpcodeInfoBits - 32)) |
| BitsOS << "(uint64_t)"; |
| - BitsOS << "OpInfo" << Table << "[MI->getOpcode()] << " << Shift << ";\n"; |
| + BitsOS << "OpInfo" << Table << "[" |
| +#ifdef CAPSTONE |
| + << "MCInst_getOpcode(MI)" |
| +#else |
| + << "MI->getOpcode()" |
| +#endif |
| + << "] << " << Shift << ";\n"; |
| // Prepare the shift for the next iteration and increment the table count. |
| Shift += TableSize; |
| ++Table; |
| } |
| |
| // Emit the initial tab character. |
| +#ifndef CAPSTONE |
| O << " O << \"\\t\";\n\n"; |
| +#endif |
| |
| O << " // Emit the opcode for the instruction.\n"; |
| O << BitsString; |
| |
| // Emit the starting string. |
| - O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" |
| - << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; |
| + O << " " |
| +#ifdef CAPSTONE |
| + << "// " |
| +#endif |
| + << "assert(Bits != 0 && \"Cannot print this instruction.\");\n" |
| +#ifdef CAPSTONE |
| + << "#ifndef CAPSTONE_DIET\n" |
| + << " SStream_concat0(O, " |
| +#else |
| + << " O << " |
| +#endif |
| + << "AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1" |
| +#ifdef CAPSTONE |
| + << ");\n" |
| + << "#endif\n\n"; |
| +#else |
| + << ");\n\n"; |
| +#endif |
| |
| // Output the table driven operand information. |
| BitsLeft = OpcodeInfoBits-AsmStrBits; |
| @@ -455,7 +492,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { |
| O << " switch ((Bits >> " |
| << (OpcodeInfoBits-BitsLeft) << ") & " |
| << ((1 << NumBits)-1) << ") {\n" |
| - << " default: llvm_unreachable(\"Invalid command number.\");\n"; |
| + << " default: " |
| +#ifdef CAPSTONE |
| + << "// " |
| +#endif |
| + << "llvm_unreachable(\"Invalid command number.\");\n"; |
| |
| // Print out all the cases. |
| for (unsigned j = 0, e = Commands.size(); j != e; ++j) { |
| @@ -536,6 +577,9 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, |
| } |
| |
| StringTable.layout(); |
| +#ifdef CAPSTONE |
| + O << "#ifndef CAPSTONE_DIET\n"; |
| +#endif |
| O << " static const char AsmStrs" << AltName << "[] = {\n"; |
| StringTable.emit(O, printChar); |
| O << " };\n\n"; |
| @@ -552,8 +596,10 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, |
| } |
| |
| void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { |
| +#ifndef CAPSTONE |
| Record *AsmWriter = Target.getAsmWriter(); |
| StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); |
| +#endif |
| const auto &Registers = Target.getRegBank().getRegisters(); |
| const std::vector<Record*> &AltNameIndices = Target.getRegAltNameIndices(); |
| bool hasAltNames = AltNameIndices.size() > 1; |
| @@ -563,12 +609,20 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { |
| "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" |
| "/// from the register set description. This returns the assembler name\n" |
| "/// for the specified register.\n" |
| +#ifdef CAPSTONE |
| + "static const char *getRegisterName(unsigned RegNo)\n{\n"; |
| +#else |
| "const char *" << Target.getName() << ClassName << "::"; |
| if (hasAltNames) |
| O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; |
| else |
| O << "getRegisterName(unsigned RegNo) {\n"; |
| - O << " assert(RegNo && RegNo < " << (Registers.size()+1) |
| +#endif |
| + O << " " |
| +#ifdef CAPSTONE |
| + << "// " |
| +#endif |
| + << "assert(RegNo && RegNo < " << (Registers.size()+1) |
| << " && \"Invalid register number!\");\n" |
| << "\n"; |
| |
| @@ -595,10 +649,22 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { |
| } |
| O << " }\n"; |
| } else { |
| +#ifdef CAPSTONE |
| + O << " //int i;\n" |
| + << " //for (i = 0; i < sizeof(RegAsmOffset); i++)\n" |
| + << " // printf(\"%s = %u\\n\", AsmStrs+RegAsmOffset[i], i + 1);\n" |
| + << " //printf(\"*************************\\n\");\n" |
| +#else |
| O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" |
| << " \"Invalid alt name index for register!\");\n" |
| +#endif |
| << " return AsmStrs+RegAsmOffset[RegNo-1];\n"; |
| } |
| +#ifdef CAPSTONE |
| + O << "#else\n" |
| + << " return NULL;\n" |
| + << "#endif\n"; |
| +#endif |
| O << "}\n"; |
| } |
| |
| @@ -1135,9 +1201,20 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { |
| } |
| |
| void AsmWriterEmitter::run(raw_ostream &O) { |
| +#ifdef CAPSTONE |
| + O << "/* Capstone Disassembly Engine */\n" |
| + "/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */\n" |
| + "\n" |
| + "#include <stdio.h>\t// debug\n" |
| + "#include <capstone/platform.h>\n" |
| + "\n" |
| + "\n"; |
| +#endif |
| EmitPrintInstruction(O); |
| EmitGetRegisterName(O); |
| +#ifndef CAPSTONE |
| EmitPrintAliasInstruction(O); |
| +#endif |
| } |
| |
| namespace llvm { |
| diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp |
| index 2c19e5d663d..6fa751e50df 100644 |
| --- a/utils/TableGen/AsmWriterInst.cpp |
| +++ b/utils/TableGen/AsmWriterInst.cpp |
| @@ -28,9 +28,13 @@ static bool isIdentChar(char C) { |
| |
| std::string AsmWriterOperand::getCode(bool PassSubtarget) const { |
| if (OperandType == isLiteralTextOperand) { |
| +#ifdef CAPSTONE |
| + return "SStream_concat0(O, \"" + Str + "\");"; |
| +#else |
| if (Str.size() == 1) |
| return "O << '" + Str + "';"; |
| return "O << \"" + Str + "\";"; |
| +#endif |
| } |
| |
| if (OperandType == isLiteralStatementOperand) |
| -- |
| 2.19.1 |
| |