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"