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/EDOperand.cpp b/tools/edis/EDOperand.cpp
index da6797e..93efd47 100644
--- a/tools/edis/EDOperand.cpp
+++ b/tools/edis/EDOperand.cpp
@@ -31,26 +31,77 @@
   MCOpIndex(mcOpIndex) {
   unsigned int numMCOperands = 0;
     
-  if(Disassembler.Key.Arch == Triple::x86 ||
-     Disassembler.Key.Arch == Triple::x86_64) {
-    uint8_t operandFlags = inst.ThisInstInfo->operandFlags[opIndex];
+  if (Disassembler.Key.Arch == Triple::x86 ||
+      Disassembler.Key.Arch == Triple::x86_64) {
+    uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
     
-    if (operandFlags & kOperandFlagImmediate) {
+    switch (operandType) {
+    default:
+      break;
+    case kOperandTypeImmediate:
       numMCOperands = 1;
-    }
-    else if (operandFlags & kOperandFlagRegister) {
+      break;
+    case kOperandTypeRegister:
       numMCOperands = 1;
-    }
-    else if (operandFlags & kOperandFlagMemory) {
-      if (operandFlags & kOperandFlagPCRelative) {
-        numMCOperands = 1;
-      }
-      else {
-        numMCOperands = 5;
-      }
-    }
-    else if (operandFlags & kOperandFlagEffectiveAddress) {
+      break;
+    case kOperandTypeX86Memory:
+      numMCOperands = 5;
+      break;
+    case kOperandTypeX86EffectiveAddress:
       numMCOperands = 4;
+      break;
+    case kOperandTypeX86PCRelative:
+      numMCOperands = 1;
+      break;
+    }
+  }
+  else if (Disassembler.Key.Arch == Triple::arm ||
+           Disassembler.Key.Arch == Triple::thumb) {
+    uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
+    
+    switch (operandType) {
+    default:
+    case kOperandTypeARMRegisterList:
+      break;
+    case kOperandTypeImmediate:
+    case kOperandTypeRegister:
+    case kOperandTypeARMBranchTarget:
+    case kOperandTypeARMSoImm:
+    case kOperandTypeThumb2SoImm:
+    case kOperandTypeARMSoImm2Part:
+    case kOperandTypeARMPredicate:
+    case kOperandTypeThumbITMask:
+    case kOperandTypeThumb2AddrModeImm8Offset:
+    case kOperandTypeARMTBAddrMode:
+    case kOperandTypeThumb2AddrModeImm8s4Offset:
+      numMCOperands = 1;
+      break;
+    case kOperandTypeThumb2SoReg:
+    case kOperandTypeARMAddrMode2Offset:
+    case kOperandTypeARMAddrMode3Offset:
+    case kOperandTypeARMAddrMode4:
+    case kOperandTypeARMAddrMode5:
+    case kOperandTypeARMAddrModePC:
+    case kOperandTypeThumb2AddrModeImm8:
+    case kOperandTypeThumb2AddrModeImm12:
+    case kOperandTypeThumb2AddrModeImm8s4:
+    case kOperandTypeThumbAddrModeRR:
+    case kOperandTypeThumbAddrModeSP:
+      numMCOperands = 2;
+      break;
+    case kOperandTypeARMSoReg:
+    case kOperandTypeARMAddrMode2:
+    case kOperandTypeARMAddrMode3:
+    case kOperandTypeThumb2AddrModeSoReg:
+    case kOperandTypeThumbAddrModeS1:
+    case kOperandTypeThumbAddrModeS2:
+    case kOperandTypeThumbAddrModeS4:
+    case kOperandTypeARMAddrMode6Offset:
+      numMCOperands = 3;
+      break;
+    case kOperandTypeARMAddrMode6:
+      numMCOperands = 4;
+      break;
     }
   }
     
@@ -63,70 +114,103 @@
 int EDOperand::evaluate(uint64_t &result,
                         EDRegisterReaderCallback callback,
                         void *arg) {
-  if (Disassembler.Key.Arch == Triple::x86 ||
-      Disassembler.Key.Arch == Triple::x86_64) {
-    uint8_t operandFlags = Inst.ThisInstInfo->operandFlags[OpIndex];
-    
-    if (operandFlags & kOperandFlagImmediate) {
+  uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
+  
+  switch (Disassembler.Key.Arch) {
+  default:
+    return -1;  
+  case Triple::x86:
+  case Triple::x86_64:    
+    switch (operandType) {
+    default:
+      return -1;
+    case kOperandTypeImmediate:
       result = Inst.Inst->getOperand(MCOpIndex).getImm();
       return 0;
-    }
-    if (operandFlags & kOperandFlagRegister) {
+    case kOperandTypeRegister:
+    {
       unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
       return callback(&result, reg, arg);
     }
-    if (operandFlags & kOperandFlagMemory ||
-        operandFlags & kOperandFlagEffectiveAddress){
-      if(operandFlags & kOperandFlagPCRelative) {
-        int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+    case kOperandTypeX86PCRelative:
+    {
+      int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
         
-        uint64_t ripVal;
+      uint64_t ripVal;
         
-        // TODO fix how we do this
+      // TODO fix how we do this
         
-        if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
-          return -1;
+      if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
+        return -1;
         
-        result = ripVal + displacement;
-        return 0;
-      }
-      else {
-        unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
-        uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
-        unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
-        int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
-        //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
-      
-        uint64_t addr = 0;
-        
-        if(baseReg) {
-          uint64_t baseVal;
-          if (callback(&baseVal, baseReg, arg))
-            return -1;
-          addr += baseVal;
-        }
-        
-        if(indexReg) {
-          uint64_t indexVal;
-          if (callback(&indexVal, indexReg, arg))
-            return -1;
-          addr += (scaleAmount * indexVal);
-        }
-        
-        addr += displacement;
-        
-        result = addr;
-        return 0;
-      }
+      result = ripVal + displacement;
+      return 0;
     }
-    return -1;
+    case kOperandTypeX86Memory:
+    case kOperandTypeX86EffectiveAddress:  
+    {
+      unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
+      uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
+      unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
+      int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
+      //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
+      
+      uint64_t addr = 0;
+        
+      if (baseReg) {
+        uint64_t baseVal;
+        if (callback(&baseVal, baseReg, arg))
+          return -1;
+        addr += baseVal;
+      }
+        
+      if (indexReg) {
+        uint64_t indexVal;
+        if (callback(&indexVal, indexReg, arg))
+          return -1;
+        addr += (scaleAmount * indexVal);
+      }
+       
+      addr += displacement;
+       
+      result = addr;
+      return 0;
+    }
+    }
+    break;
+  case Triple::arm:
+  case Triple::thumb:
+    switch (operandType) {
+    default:
+      return -1;
+    case kOperandTypeImmediate:
+      result = Inst.Inst->getOperand(MCOpIndex).getImm();
+      return 0;
+    case kOperandTypeRegister:
+    {
+      unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
+      return callback(&result, reg, arg);
+    }
+    case kOperandTypeARMBranchTarget:
+    {
+      int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+      
+      uint64_t pcVal;
+      
+      if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
+        return -1;
+      
+      result = pcVal + displacement;
+      return 0;
+    }
+    }
   }
   
   return -1;
 }
 
 int EDOperand::isRegister() {
-  return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagRegister);
+  return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
 }
 
 unsigned EDOperand::regVal() {
@@ -134,7 +218,7 @@
 }
 
 int EDOperand::isImmediate() {
-  return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagImmediate);
+  return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
 }
 
 uint64_t EDOperand::immediateVal() {
@@ -142,7 +226,33 @@
 }
 
 int EDOperand::isMemory() {
-  return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagMemory);
+  switch (Inst.ThisInstInfo->operandFlags[OpIndex]) {
+  default:
+    return 0;
+  case kOperandTypeX86Memory:
+  case kOperandTypeARMSoReg:
+  case kOperandTypeARMSoImm:
+  case kOperandTypeARMAddrMode2:
+  case kOperandTypeARMAddrMode2Offset:
+  case kOperandTypeARMAddrMode3:
+  case kOperandTypeARMAddrMode3Offset:
+  case kOperandTypeARMAddrMode4:
+  case kOperandTypeARMAddrMode5:
+  case kOperandTypeARMAddrMode6:
+  case kOperandTypeARMAddrModePC:
+  case kOperandTypeThumbAddrModeS1:
+  case kOperandTypeThumbAddrModeS2:
+  case kOperandTypeThumbAddrModeS4:
+  case kOperandTypeThumbAddrModeRR:
+  case kOperandTypeThumbAddrModeSP:
+  case kOperandTypeThumb2SoImm:
+  case kOperandTypeThumb2AddrModeImm8:
+  case kOperandTypeThumb2AddrModeImm8Offset:
+  case kOperandTypeThumb2AddrModeImm12:
+  case kOperandTypeThumb2AddrModeSoReg:
+  case kOperandTypeThumb2AddrModeImm8s4:
+    return 1;
+  }
 }
 
 #ifdef __BLOCKS__