Added support for ARM disassembly to edis.

I also added a rule to the ARM target's Makefile to
build the ARM-specific instruction information table
for the enhanced disassembler.

I will add the test harness for all this stuff in
a separate commit.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100735 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/edis/EDDisassembler.cpp b/tools/edis/EDDisassembler.cpp
index 8729b49..072df82 100644
--- a/tools/edis/EDDisassembler.cpp
+++ b/tools/edis/EDDisassembler.cpp
@@ -13,6 +13,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "EDDisassembler.h"
+#include "EDInst.h"
+
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -36,10 +39,8 @@
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetSelect.h"
 
-#include "EDDisassembler.h"
-#include "EDInst.h"
-
 #include "../../lib/Target/X86/X86GenEDInfo.inc"
+#include "../../lib/Target/ARM/ARMGenEDInfo.inc"
 
 using namespace llvm;
 
@@ -55,6 +56,8 @@
 static struct InfoMap infomap[] = {
   { Triple::x86,          "i386-unknown-unknown",   instInfoX86 },
   { Triple::x86_64,       "x86_64-unknown-unknown", instInfoX86 },
+  { Triple::arm,          "arm-unknown-unknown",    instInfoARM },
+  { Triple::thumb,        "thumb-unknown-unknown",  instInfoARM },
   { Triple::InvalidArch,  NULL,                     NULL        }
 };
 
@@ -66,7 +69,7 @@
   unsigned int infoIndex;
   
   for (infoIndex = 0; infomap[infoIndex].String != NULL; ++infoIndex) {
-    if(arch == infomap[infoIndex].Arch)
+    if (arch == infomap[infoIndex].Arch)
       return &infomap[infoIndex];
   }
   
@@ -95,6 +98,11 @@
       return 1;
     else
       return -1;
+  case kEDAssemblySyntaxARMUAL:
+    if (arch == Triple::arm || arch == Triple::thumb)
+      return 0;
+    else
+      return -1;
   }
 }
 
@@ -112,6 +120,7 @@
   sInitialized = true;
   
   BRINGUP_TARGET(X86)
+  BRINGUP_TARGET(ARM)
 }
 
 #undef BRINGUP_TARGET
@@ -126,10 +135,9 @@
   
   if (i != sDisassemblers.end()) {
     return i->second;
-  }
-  else {
+  } else {
     EDDisassembler* sdd = new EDDisassembler(key);
-    if(!sdd->valid()) {
+    if (!sdd->valid()) {
       delete sdd;
       return NULL;
     }
@@ -150,11 +158,16 @@
 }
 
 EDDisassembler::EDDisassembler(CPUKey &key) : 
-  Valid(false), ErrorString(), ErrorStream(ErrorString), Key(key) {
+  Valid(false), 
+  HasSemantics(false), 
+  ErrorStream(nulls()), 
+  Key(key) {
   const InfoMap *infoMap = infoFromArch(key.Arch);
   
   if (!infoMap)
     return;
+    
+  InstInfos = infoMap->Info;
   
   const char *triple = infoMap->String;
   
@@ -182,6 +195,8 @@
   
   if (!registerInfo)
     return;
+    
+  initMaps(*registerInfo);
   
   AsmInfo.reset(Tgt->createAsmInfo(tripleString));
   
@@ -212,7 +227,7 @@
 }
 
 EDDisassembler::~EDDisassembler() {
-  if(!valid())
+  if (!valid())
     return;
 }
 
@@ -230,10 +245,10 @@
     uint64_t getBase() const { return 0x0; }
     uint64_t getExtent() const { return (uint64_t)-1; }
     int readByte(uint64_t address, uint8_t *ptr) const {
-      if(!Callback)
+      if (!Callback)
         return -1;
       
-      if(Callback(ptr, address, Arg))
+      if (Callback(ptr, address, Arg))
         return -1;
       
       return 0;
@@ -256,9 +271,10 @@
                                     ErrorStream)) {
     delete inst;
     return NULL;
-  }
-  else {
-    const InstInfo *thisInstInfo = &InstInfos[inst->getOpcode()];
+  } else {
+    const InstInfo *thisInstInfo;
+
+    thisInstInfo = &InstInfos[inst->getOpcode()];
     
     EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
     return sdInst;
@@ -276,8 +292,11 @@
     RegRMap[registerName] = registerIndex;
   }
   
-  if (Key.Arch == Triple::x86 ||
-      Key.Arch == Triple::x86_64) {
+  switch (Key.Arch) {
+  default:
+    break;
+  case Triple::x86:
+  case Triple::x86_64:
     stackPointers.insert(registerIDWithName("SP"));
     stackPointers.insert(registerIDWithName("ESP"));
     stackPointers.insert(registerIDWithName("RSP"));
@@ -285,6 +304,13 @@
     programCounters.insert(registerIDWithName("IP"));
     programCounters.insert(registerIDWithName("EIP"));
     programCounters.insert(registerIDWithName("RIP"));
+    break;
+  case Triple::arm:
+  case Triple::thumb:
+    stackPointers.insert(registerIDWithName("SP"));
+    
+    programCounters.insert(registerIDWithName("PC"));
+    break;  
   }
 }
 
@@ -329,6 +355,16 @@
                               const std::string &str) {
   int ret = 0;
   
+  switch (Key.Arch) {
+  default:
+    return -1;
+  case Triple::x86:
+  case Triple::x86_64:
+  case Triple::arm:
+  case Triple::thumb:
+    break;
+  }
+  
   const char *cStr = str.c_str();
   MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
   
@@ -343,14 +379,14 @@
   OwningPtr<TargetAsmParser> TargetParser(Tgt->createAsmParser(genericParser));
   
   AsmToken OpcodeToken = genericParser.Lex();
+  genericParser.Lex();  // consume next token, because specificParser expects us to
   
-  if(OpcodeToken.is(AsmToken::Identifier)) {
+  if (OpcodeToken.is(AsmToken::Identifier)) {
     instName = OpcodeToken.getString();
     instLoc = OpcodeToken.getLoc();
     if (TargetParser->ParseInstruction(instName, instLoc, operands))
       ret = -1;
-  }
-  else {
+  } else {
     ret = -1;
   }