Fix FMDRR encoding.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59088 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 08372ce..7e1e804 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -342,6 +342,7 @@
     break;
   case ARMII::VFPConv1Frm:
   case ARMII::VFPConv2Frm:
+  case ARMII::VFPConv3Frm:
     emitVFPConversionInstruction(MI);
     break;
   case ARMII::VFPLdStFrm:
@@ -1080,27 +1081,41 @@
   // Set the conditional execution predicate
   Binary |= II->getPredicate(&MI) << ARMII::CondShift;
 
-  unsigned OpIdx = 0;
+  // FMDRR encodes registers in reverse order.
+  unsigned Form = TID.TSFlags & ARMII::FormMask;
+  unsigned OpIdx = (Form == ARMII::VFPConv2Frm) ? 2 : 0;
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx++);
+  unsigned RegD = getMachineOpValue(MI, OpIdx);
   Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
   Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  if (Form == ARMII::VFPConv2Frm)
+    --OpIdx;
+  else
+    ++OpIdx;
 
   // Encode Dn / Sn.
-  if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPConv1Frm) {
-    unsigned RegN = getMachineOpValue(MI, OpIdx++);
+  if (Form == ARMII::VFPConv1Frm || Form == ARMII::VFPConv2Frm) {
+    unsigned RegN = getMachineOpValue(MI, OpIdx);
     Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
     Binary |= (RegN & 0x10) << ARMII::N_BitShift;
+    if (Form == ARMII::VFPConv2Frm)
+      --OpIdx;
+    else
+      ++OpIdx;
 
     // FMRS / FMSR do not have Rm.
-    if (!TID.OpInfo[2].isPredicate()) {
-      unsigned RegM = getMachineOpValue(MI, OpIdx++);
+    if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
+      unsigned RegM = getMachineOpValue(MI, OpIdx);
       Binary |= (RegM & 0x0f);
       Binary |= (RegM & 0x10) << ARMII::M_BitShift;
+    } else if (Form == ARMII::VFPConv2Frm) {
+      // FMDRR encodes definition register in Dm field.
+      Binary |= getMachineOpValue(MI, 0);
     }
   } else {
-    unsigned RegM = getMachineOpValue(MI, OpIdx++);
+    assert(Form == ARMII::VFPConv3Frm && "Unsupported format!");
+    unsigned RegM = getMachineOpValue(MI, OpIdx);
     Binary |= (RegM & 0x0f);
     Binary |= (RegM & 0x10) << ARMII::M_BitShift;
   }