Support Thumb mode encoding of NEON instructions.
authorBob Wilson <bob.wilson@apple.com>
Mon, 28 Jun 2010 21:12:19 +0000 (21:12 +0000)
committerBob Wilson <bob.wilson@apple.com>
Mon, 28 Jun 2010 21:12:19 +0000 (21:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107068 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp

index 49e83c3f8a9632ed0f1ea55ea7a5327949e894de..cf3ae9817450ec23962676bfeb4ebd8ba36c1db4 100644 (file)
@@ -1585,6 +1585,15 @@ static unsigned encodeNEONRm(const MachineInstr &MI, unsigned OpIdx) {
   return Binary;
 }
 
+/// convertNEONDataProcToThumb - Convert the ARM mode encoding for a NEON
+/// data-processing instruction to the corresponding Thumb encoding.
+static unsigned convertNEONDataProcToThumb(unsigned Binary) {
+  assert((Binary & 0xfe000000) == 0xf2000000 &&
+         "not an ARM NEON data-processing instruction");
+  unsigned UBit = (Binary >> 24) & 1;
+  return 0xef000000 | (UBit << 28) | (Binary & 0xffffff);
+}
+
 void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
   unsigned Binary = getBinaryCodeForInstr(MI);
 
@@ -1630,6 +1639,8 @@ void ARMCodeEmitter::emitNEON1RegModImmInstruction(const MachineInstr &MI) {
   Binary |= (Imm3 << 16);
   unsigned Imm4 = Imm & 0xf;
   Binary |= Imm4;
+  if (Subtarget->isThumb())
+    Binary = convertNEONDataProcToThumb(Binary);
   emitWordLE(Binary);
 }
 
@@ -1642,6 +1653,8 @@ void ARMCodeEmitter::emitNEON2RegInstruction(const MachineInstr &MI) {
   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
     ++OpIdx;
   Binary |= encodeNEONRm(MI, OpIdx);
+  if (Subtarget->isThumb())
+    Binary = convertNEONDataProcToThumb(Binary);
   // FIXME: This does not handle VDUPfdf or VDUPfqf.
   emitWordLE(Binary);
 }
@@ -1658,6 +1671,8 @@ void ARMCodeEmitter::emitNEON3RegInstruction(const MachineInstr &MI) {
   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
     ++OpIdx;
   Binary |= encodeNEONRm(MI, OpIdx);
+  if (Subtarget->isThumb())
+    Binary = convertNEONDataProcToThumb(Binary);
   // FIXME: This does not handle VMOVDneon or VMOVQ.
   emitWordLE(Binary);
 }