Fixed a nasty layering violation in the edis source
[oota-llvm.git] / lib / Target / ARM / Disassembler / ARMDisassemblerCore.cpp
index 41c8c228914c7984919d307d05963a522a35bca8..98bb6716c7fa25cf68207eee34da6169d951b14a 100644 (file)
@@ -8,8 +8,8 @@
 //===----------------------------------------------------------------------===//
 //
 // This file is part of the ARM Disassembler.
-// It contains code to represent the core concepts of Builder, Builder Factory,
-// as well as the Algorithm to solve the problem of disassembling an ARM instr.
+// It contains code to represent the core concepts of Builder and DisassembleFP
+// to solve the problem of disassembling an ARM instr.
 //
 //===----------------------------------------------------------------------===//
 
@@ -478,7 +478,7 @@ static inline ARM_AM::AMSubMode getAMSubModeForBits(unsigned bits) {
 /// followed by possible src(s).
 ///
 /// The processing of the predicate, and the 'S' modifier bit, if MI modifies
-/// the CPSR, is factored into ARMBasicMCBuilder's class method named
+/// the CPSR, is factored into ARMBasicMCBuilder's method named
 /// TryPredicateAndSBitModifier.
 
 static bool DisassemblePseudo(MCInst &MI, unsigned Opcode, uint32_t insn,
@@ -694,6 +694,7 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     return DisassembleCoprocessor(MI, Opcode, insn, NumOps, NumOpsAdded);
 
   const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
+  if (!OpInfo) return false;
 
   // MRS and MRSsys take one GPR reg Rd.
   if (Opcode == ARM::MRS || Opcode == ARM::MRSsys) {
@@ -794,6 +795,8 @@ static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, BO) {
 
   const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
+  if (!OpInfo) return false;
+
   unsigned &OpIdx = NumOpsAdded;
 
   OpIdx = 0;
@@ -1124,14 +1127,16 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, bool isStore) {
 
   const TargetInstrDesc &TID = ARMInsts[Opcode];
-  unsigned short NumDefs = TID.getNumDefs();
   bool isPrePost = isPrePostLdSt(TID.TSFlags);
   const TargetOperandInfo *OpInfo = TID.OpInfo;
+  if (!OpInfo) return false;
+
   unsigned &OpIdx = NumOpsAdded;
 
   OpIdx = 0;
 
-  assert(((!isStore && NumDefs > 0) || (isStore && (NumDefs == 0 || isPrePost)))
+  assert(((!isStore && TID.getNumDefs() > 0) ||
+          (isStore && (TID.getNumDefs() == 0 || isPrePost)))
          && "Invalid arguments");
 
   // Operand 0 of a pre- and post-indexed store is the address base writeback.
@@ -1235,14 +1240,16 @@ static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, bool isStore) {
 
   const TargetInstrDesc &TID = ARMInsts[Opcode];
-  unsigned short NumDefs = TID.getNumDefs();
   bool isPrePost = isPrePostLdSt(TID.TSFlags);
   const TargetOperandInfo *OpInfo = TID.OpInfo;
+  if (!OpInfo) return false;
+
   unsigned &OpIdx = NumOpsAdded;
 
   OpIdx = 0;
 
-  assert(((!isStore && NumDefs > 0) || (isStore && (NumDefs == 0 || isPrePost)))
+  assert(((!isStore && TID.getNumDefs() > 0) ||
+          (isStore && (TID.getNumDefs() == 0 || isPrePost)))
          && "Invalid arguments");
 
   // Operand 0 of a pre- and post-indexed store is the address base writeback.
@@ -1391,6 +1398,8 @@ static bool DisassembleLdStExFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, BO) {
 
   const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
+  if (!OpInfo) return false;
+
   unsigned &OpIdx = NumOpsAdded;
 
   OpIdx = 0;
@@ -1681,6 +1690,7 @@ static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
 
   const TargetInstrDesc &TID = ARMInsts[Opcode];
   const TargetOperandInfo *OpInfo = TID.OpInfo;
+  if (!OpInfo) return false;
 
   bool SP = slice(insn, 8, 8) == 0; // A8.6.295 & A8.6.297
   bool fixed_point = slice(insn, 17, 17) == 1; // A8.6.297
@@ -1986,7 +1996,7 @@ static bool DisassembleVFPMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
 // D = Inst{22}, Vd = Inst{15-12}
 static unsigned decodeNEONRd(uint32_t insn) {
   return ((insn >> ARMII::NEON_D_BitShift) & 1) << 4
-    | (insn >> ARMII::NEON_RegRdShift) & ARMII::NEONRegMask;
+    | ((insn >> ARMII::NEON_RegRdShift) & ARMII::NEONRegMask);
 }
 
 // Extract/Decode NEON N/Vn:
@@ -1997,7 +2007,7 @@ static unsigned decodeNEONRd(uint32_t insn) {
 // N = Inst{7}, Vn = Inst{19-16}
 static unsigned decodeNEONRn(uint32_t insn) {
   return ((insn >> ARMII::NEON_N_BitShift) & 1) << 4
-    | (insn >> ARMII::NEON_RegRnShift) & ARMII::NEONRegMask;
+    | ((insn >> ARMII::NEON_RegRnShift) & ARMII::NEONRegMask);
 }
 
 // Extract/Decode NEON M/Vm:
@@ -2008,7 +2018,7 @@ static unsigned decodeNEONRn(uint32_t insn) {
 // M = Inst{5}, Vm = Inst{3-0}
 static unsigned decodeNEONRm(uint32_t insn) {
   return ((insn >> ARMII::NEON_M_BitShift) & 1) << 4
-    | (insn >> ARMII::NEON_RegRmShift) & ARMII::NEONRegMask;
+    | ((insn >> ARMII::NEON_RegRmShift) & ARMII::NEONRegMask);
 }
 
 namespace {
@@ -2766,6 +2776,7 @@ static bool DisassembleNVTBLFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
 
   const TargetInstrDesc &TID = ARMInsts[Opcode];
   const TargetOperandInfo *OpInfo = TID.OpInfo;
+  if (!OpInfo) return false;
 
   assert(NumOps >= 3 &&
          OpInfo[0].RegClass == ARM::DPRRegClassID &&
@@ -2828,10 +2839,10 @@ static bool DisassembleNEONGetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, BO) {
 
   const TargetInstrDesc &TID = ARMInsts[Opcode];
-  unsigned short NumDefs = TID.getNumDefs();
   const TargetOperandInfo *OpInfo = TID.OpInfo;
+  if (!OpInfo) return false;
 
-  assert(NumDefs == 1 && NumOps >= 3 &&
+  assert(TID.getNumDefs() == 1 && NumOps >= 3 &&
          OpInfo[0].RegClass == ARM::GPRRegClassID &&
          OpInfo[1].RegClass == ARM::DPRRegClassID &&
          OpInfo[2].RegClass == 0 &&
@@ -2862,10 +2873,10 @@ static bool DisassembleNEONSetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
     unsigned short NumOps, unsigned &NumOpsAdded, BO) {
 
   const TargetInstrDesc &TID = ARMInsts[Opcode];
-  unsigned short NumDefs = TID.getNumDefs();
   const TargetOperandInfo *OpInfo = TID.OpInfo;
+  if (!OpInfo) return false;
 
-  assert(NumDefs == 1 && NumOps >= 3 &&
+  assert(TID.getNumDefs() == 1 && NumOps >= 3 &&
          OpInfo[0].RegClass == ARM::DPRRegClassID &&
          OpInfo[1].RegClass == ARM::DPRRegClassID &&
          TID.getOperandConstraint(1, TOI::TIED_TO) != -1 &&
@@ -3127,31 +3138,12 @@ static const DisassembleFP FuncPtrs[] = {
   NULL
 };
 
-/// Algorithms - Algorithms stores a map from Format to ARMAlgorithm*.
-static std::vector<ARMAlgorithm*> Algorithms;
-
-/// GetInstance - GetInstance returns an instance of ARMAlgorithm given the
-/// encoding Format.  API clients should not free up the returned instance.
-ARMAlgorithm *ARMAlgorithm::GetInstance(ARMFormat Format) {
-  /// Init the first time.
-  if (Algorithms.size() == 0) {
-    Algorithms.resize(array_lengthof(FuncPtrs));
-    for (unsigned i = 0, num = array_lengthof(FuncPtrs); i < num; ++i)
-      if (FuncPtrs[i])
-        Algorithms[i] = new ARMAlgorithm(FuncPtrs[i]);
-      else
-        Algorithms[i] = NULL;
-  }
-  return Algorithms[Format];
-}
-
-
 /// BuildIt - BuildIt performs the build step for this ARM Basic MC Builder.
 /// The general idea is to set the Opcode for the MCInst, followed by adding
 /// the appropriate MCOperands to the MCInst.  ARM Basic MC Builder delegates
-/// to the Algo (ARM Disassemble Algorithm) object to perform Format-specific
-/// disassembly, followed by class method TryPredicateAndSBitModifier() to do
-/// PredicateOperand and OptionalDefOperand which follow the Dst/Src Operands.
+/// to the Format-specific disassemble function for disassembly, followed by
+/// TryPredicateAndSBitModifier() to do PredicateOperand and OptionalDefOperand
+/// which follow the Dst/Src Operands.
 bool ARMBasicMCBuilder::BuildIt(MCInst &MI, uint32_t insn) {
   // Stage 1 sets the Opcode.
   MI.setOpcode(Opcode);
@@ -3159,9 +3151,12 @@ bool ARMBasicMCBuilder::BuildIt(MCInst &MI, uint32_t insn) {
   if (NumOps == 0)
     return true;
 
-  // Stage 2 calls the ARM Disassembly Algorithm to build the operand list.
+  // Stage 2 calls the format-specific disassemble function to build the operand
+  // list.
+  if (Disasm == NULL)
+    return false;
   unsigned NumOpsAdded = 0;
-  bool OK = Algo.Solve(MI, Opcode, insn, NumOps, NumOpsAdded, this);
+  bool OK = (*Disasm)(MI, Opcode, insn, NumOps, NumOpsAdded, this);
 
   if (!OK) return false;
   if (NumOpsAdded >= NumOps)
@@ -3247,6 +3242,15 @@ bool ARMBasicMCBuilder::RunBuildAfterHook(bool Status, MCInst &MI,
   return Status;
 }
 
+/// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
+ARMBasicMCBuilder::ARMBasicMCBuilder(unsigned opc, ARMFormat format,
+                                     unsigned short num)
+  : Opcode(opc), Format(format), NumOps(num), SP(0) {
+  unsigned Idx = (unsigned)format;
+  assert(Idx < (array_lengthof(FuncPtrs) - 1) && "Unknown format");
+  Disasm = FuncPtrs[Idx];
+}
+
 /// CreateMCBuilder - Return an ARMBasicMCBuilder that can build up the MC
 /// infrastructure of an MCInst given the Opcode and Format of the instr.
 /// Return NULL if it fails to create/return a proper builder.  API clients
@@ -3254,10 +3258,6 @@ bool ARMBasicMCBuilder::RunBuildAfterHook(bool Status, MCInst &MI,
 /// performed by the API clients to improve performance.
 ARMBasicMCBuilder *llvm::CreateMCBuilder(unsigned Opcode, ARMFormat Format) {
 
-  ARMAlgorithm *Algo = ARMAlgorithm::GetInstance(Format);
-  if (!Algo)
-    return NULL;
-
   return new ARMBasicMCBuilder(Opcode, Format,
-                               ARMInsts[Opcode].getNumOperands(), *Algo);
+                               ARMInsts[Opcode].getNumOperands());
 }