The tLDR et al instructions were emitting either a reg/reg or reg/imm
instruction based on the t_addrmode_s# mode and what it returned. There is some
obvious badness to this. In particular, it's hard to do MC-encoding when the
instruction may change out from underneath you after the t_addrmode_s# variable
is finally resolved.

The solution is to revert a long-ago change that merged the reg/reg and reg/imm
versions. There is the addition of several new addressing modes. They no longer
have extraneous operands associated with them. I.e., if it's reg/reg we don't
have to have a dummy zero immediate tacked on to the SDNode.

There are some obvious cleanups here, which will happen shortly.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121747 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index c21a07c..8322d70 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -236,11 +236,16 @@
     int64_t Value = CE->getValue();
     return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
   }
-  bool isMemModeThumb() const {
+  bool isMemModeRegThumb() const {
+    if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback)
+      return false;
+    return !Mem.Offset || !isa<MCConstantExpr>(Mem.Offset);
+  }
+  bool isMemModeImmThumb() const {
     if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback)
       return false;
 
-    if (!Mem.Offset) return true;
+    if (!Mem.Offset) return false;
 
     const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
     if (!CE) return false;
@@ -324,19 +329,18 @@
     }
   }
 
-  void addMemModeThumbOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 3 && isMemModeThumb() && "Invalid number of operands!");
+  void addMemModeRegThumbOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 2 && isMemModeRegThumb() && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
+  }
 
-    if (Mem.Offset) {
-      const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
-      assert(CE && "Non-constant mode offset operand!");
-      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
-      Inst.addOperand(MCOperand::CreateReg(0));
-    } else {
-      Inst.addOperand(MCOperand::CreateImm(0));
-      Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
-    }
+  void addMemModeImmThumbOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 2 && isMemModeImmThumb() && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+    assert(CE && "Non-constant mode offset operand!");
+    Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
   }
 
   virtual void dump(raw_ostream &OS) const;