Encode VFP conversion instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59074 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index b39ab7f8..29a8f31 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -122,6 +122,8 @@
 
     void emitVFPArithInstruction(const MachineInstr &MI);
 
+    void emitVFPConversionInstruction(const MachineInstr &MI);
+
     /// getBinaryCodeForInstr - This function, generated by the
     /// CodeEmitterGenerator using TableGen, produces the binary encoding for
     /// machine instructions.
@@ -320,6 +322,10 @@
   case ARMII::VFPBinaryFrm:
     emitVFPArithInstruction(MI);
     break;
+  case ARMII::VFPConv1Frm:
+  case ARMII::VFPConv2Frm:
+    emitVFPConversionInstruction(MI);
+    break;
   }
 }
 
@@ -999,7 +1005,7 @@
 
   // Encode Dd / Sd.
   unsigned RegD = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegD & 0x0f) << ARMII::RegFdShift;
+  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
   Binary |= (RegD & 0x10) << ARMII::D_BitShift;
 
   // If this is a two-address operand, skip it, e.g. FMACD.
@@ -1009,7 +1015,7 @@
   // Encode Dn / Sn.
   if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) {
     unsigned RegN = getMachineOpValue(MI, OpIdx++);
-    Binary |= (RegN & 0x0f);
+    Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
     Binary |= (RegN & 0x10) << ARMII::N_BitShift;
   }
 
@@ -1021,4 +1027,41 @@
   emitWordLE(Binary);
 }
 
+void ARMCodeEmitter::emitVFPConversionInstruction(const MachineInstr &MI) {
+  const TargetInstrDesc &TID = MI.getDesc();
+
+  // Part of binary is determined by TableGn.
+  unsigned Binary = getBinaryCodeForInstr(MI);
+
+  // Set the conditional execution predicate
+  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+  unsigned OpIdx = 0;
+
+  // Encode Dd / Sd.
+  unsigned RegD = getMachineOpValue(MI, OpIdx++);
+  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
+  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+
+  // Encode Dn / Sn.
+  if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPConv1Frm) {
+    unsigned RegN = getMachineOpValue(MI, OpIdx++);
+    Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
+    Binary |= (RegN & 0x10) << ARMII::N_BitShift;
+
+    // FMRS / FMSR do not have Rm.
+    if (!TID.OpInfo[2].isPredicate()) {
+      unsigned RegM = getMachineOpValue(MI, OpIdx++);
+      Binary |= (RegM & 0x0f);
+      Binary |= (RegM & 0x10) << ARMII::M_BitShift;
+    }
+  } else {
+    unsigned RegM = getMachineOpValue(MI, OpIdx++);
+    Binary |= (RegM & 0x0f);
+    Binary |= (RegM & 0x10) << ARMII::M_BitShift;
+  }
+
+  emitWordLE(Binary);
+}
+
 #include "ARMGenCodeEmitter.inc"