[RuntimeDyld] Add support for absolute symbols.
[oota-llvm.git] / utils / TableGen / DisassemblerEmitter.cpp
index 07313d19e87426c57c654f6585b3fe730e22aa90..e8595271bccef863180eec7ab7630fc1c71ecebb 100644 (file)
@@ -7,14 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "DisassemblerEmitter.h"
 #include "CodeGenTarget.h"
-#include "Error.h"
-#include "Record.h"
 #include "X86DisassemblerTables.h"
 #include "X86RecognizableInstr.h"
-#include "ARMDecoderEmitter.h"
-#include "FixedLenDecoderEmitter.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
 
 using namespace llvm;
 using namespace llvm::X86Disassembler;
@@ -95,45 +93,57 @@ using namespace llvm::X86Disassembler;
 /// X86RecognizableInstr.cpp contains the implementation for a single
 ///   instruction.
 
-void DisassemblerEmitter::run(raw_ostream &OS) {
-  CodeGenTarget Target(Records);
+namespace llvm {
+
+extern void EmitFixedLenDecoder(RecordKeeper &RK, raw_ostream &OS,
+                                std::string PredicateNamespace,
+                                std::string GPrefix,
+                                std::string GPostfix,
+                                std::string ROK,
+                                std::string RFail,
+                                std::string L);
 
-  OS << "/*===- TableGen'erated file "
-     << "---------------------------------------*- C -*-===*\n"
-     << " *\n"
-     << " * " << Target.getName() << " Disassembler\n"
-     << " *\n"
-     << " * Automatically generated file, do not edit!\n"
-     << " *\n"
-     << " *===---------------------------------------------------------------"
-     << "-------===*/\n";
+void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) {
+  CodeGenTarget Target(Records);
+  emitSourceFileHeader(" * " + Target.getName() + " Disassembler", OS);
 
   // X86 uses a custom disassembler.
   if (Target.getName() == "X86") {
     DisassemblerTables Tables;
-  
+
     const std::vector<const CodeGenInstruction*> &numberedInstructions =
       Target.getInstructionsByEnumValue();
-    
+
     for (unsigned i = 0, e = numberedInstructions.size(); i != e; ++i)
       RecognizableInstr::processInstr(Tables, *numberedInstructions[i], i);
 
-    // FIXME: As long as we are using exceptions, might as well drop this to the
-    // actual conflict site.
-    if (Tables.hasConflicts())
-      throw TGError(Target.getTargetRecord()->getLoc(),
-                    "Primary decode conflict");
+    if (Tables.hasConflicts()) {
+      PrintError(Target.getTargetRecord()->getLoc(), "Primary decode conflict");
+      return;
+    }
 
     Tables.emit(OS);
     return;
   }
 
-  // Fixed-instruction-length targets use a common disassembler.
-  // ARM use its own implementation for now.
-  if (Target.getName() == "ARM") {
-    ARMDecoderEmitter(Records).run(OS);
+  // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses.
+  if (Target.getName() == "ARM" || Target.getName() == "Thumb" ||
+      Target.getName() == "AArch64" || Target.getName() == "ARM64") {
+    std::string PredicateNamespace = Target.getName();
+    if (PredicateNamespace == "Thumb")
+      PredicateNamespace = "ARM";
+
+    EmitFixedLenDecoder(Records, OS, PredicateNamespace,
+                        "if (!Check(S, ", "))",
+                        "S", "MCDisassembler::Fail",
+                        "  MCDisassembler::DecodeStatus S = "
+                          "MCDisassembler::Success;\n(void)S;");
     return;
-  }  
+  }
 
-  FixedLenDecoderEmitter(Records).run(OS);
+  EmitFixedLenDecoder(Records, OS, Target.getName(),
+                      "if (", " == MCDisassembler::Fail)",
+                      "MCDisassembler::Success", "MCDisassembler::Fail", "");
 }
+
+} // End llvm namespace