summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMCodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMCodeEmitter.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMCodeEmitter.cpp47
1 files changed, 45 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp
index b39ab7f833d..29a8f31a514 100644
--- a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -122,6 +122,8 @@ namespace {
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 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
case ARMII::VFPBinaryFrm:
emitVFPArithInstruction(MI);
break;
+ case ARMII::VFPConv1Frm:
+ case ARMII::VFPConv2Frm:
+ emitVFPConversionInstruction(MI);
+ break;
}
}
@@ -999,7 +1005,7 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
// 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 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
// 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 @@ void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
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"
OpenPOWER on IntegriCloud