Fix encoding of single-precision VFP registers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59102 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 5b7bc97..d6d9814 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -1053,9 +1053,16 @@
          (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!");
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
-  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  unsigned RegD = MI.getOperand(OpIdx++).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
+    
 
   // If this is a two-address operand, skip it, e.g. FMACD.
   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
@@ -1063,15 +1070,27 @@
 
   // Encode Dn / Sn.
   if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) {
-    unsigned RegN = getMachineOpValue(MI, OpIdx++);
-    Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
-    Binary |= (RegN & 0x10) << ARMII::N_BitShift;
+    unsigned RegN = MI.getOperand(OpIdx++).getReg();
+    isSPVFP = false;
+    RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
+    if (!isSPVFP)
+      Binary |=   RegN               << ARMII::RegRnShift;
+    else {
+      Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
+      Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
+    }
   }
 
   // Encode Dm / Sm.
-  unsigned RegM = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegM & 0x0f);
-  Binary |= (RegM & 0x10) << ARMII::M_BitShift;
+  unsigned RegM = MI.getOperand(OpIdx++).getReg();
+  isSPVFP = false;
+  RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegM;
+  else {
+    Binary |= ((RegM & 0x1E) >> 1);
+    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
+  }
   
   emitWordLE(Binary);
 }
@@ -1087,41 +1106,65 @@
 
   // FMDRR encodes registers in reverse order.
   unsigned Form = TID.TSFlags & ARMII::FormMask;
-  unsigned OpIdx = (Form == ARMII::VFPConv2Frm) ? 2 : 0;
+  unsigned OpIdx = (Form == ARMII::VFPConv2Frm)
+    ? MI.findFirstPredOperandIdx()-1 : 0;
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx);
-  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
-  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  unsigned RegD = MI.getOperand(OpIdx).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
   if (Form == ARMII::VFPConv2Frm)
     --OpIdx;
   else
     ++OpIdx;
 
-  // Encode Dn / Sn.
-  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.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);
+  if (Form == ARMII::VFPConv3Frm) {
+    unsigned RegM = MI.getOperand(OpIdx).getReg();
+    isSPVFP = false;
+    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+    if (!isSPVFP)
+      Binary |=   RegM;
+    else {
+      Binary |= ((RegM & 0x1E) >> 1);
+      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
     }
-  } else {
-    assert(Form == ARMII::VFPConv3Frm && "Unsupported format!");
-    unsigned RegM = getMachineOpValue(MI, OpIdx);
-    Binary |= (RegM & 0x0f);
-    Binary |= (RegM & 0x10) << ARMII::M_BitShift;
+
+    emitWordLE(Binary);
+    return;
+  }
+
+  // Encode Dn / Sn.
+  unsigned RegN = MI.getOperand(OpIdx).getReg();
+  isSPVFP = false;
+  RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegN               << ARMII::RegRnShift;
+  else {
+    Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
+    Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
+  }
+  if (Form == ARMII::VFPConv2Frm)
+    --OpIdx;
+  else
+    ++OpIdx;
+
+  // FMRS / FMSR do not have Rm.
+  if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
+    unsigned RegM = MI.getOperand(OpIdx).getReg();
+    isSPVFP = false;
+    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+    if (!isSPVFP)
+      Binary |=   RegM;
+    else {
+      Binary |= ((RegM & 0x1E) >> 1);
+      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
+    }
   }
 
   emitWordLE(Binary);
@@ -1137,9 +1180,15 @@
   unsigned OpIdx = 0;
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
-  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  unsigned RegD = MI.getOperand(OpIdx++).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
 
   // Encode address base.
   const MachineOperand &Base = MI.getOperand(OpIdx++);
@@ -1184,8 +1233,15 @@
     Binary |= 0x1 << ARMII::W_BitShift;
 
   // First register is encoded in Dd.
-  unsigned FirstReg = MI.getOperand(4).getReg();
-  Binary |= ARMRegisterInfo::getRegisterNumbering(FirstReg)<< ARMII::RegRdShift;
+  unsigned RegD = MI.getOperand(4).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
 
   // Number of registers are encoded in offset field.
   unsigned NumRegs = 1;