Add support for encoding NEON VMOV (from core register to scalar) instructions.
authorBob Wilson <bob.wilson@apple.com>
Tue, 29 Jun 2010 17:34:07 +0000 (17:34 +0000)
committerBob Wilson <bob.wilson@apple.com>
Tue, 29 Jun 2010 17:34:07 +0000 (17:34 +0000)
The encoding is the same as VMOV (from scalar to core register) except that
the operands are in different places.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107167 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp

index f26074d358a03a1d6cee8162d22242de8692d826..2c8939fdf0fb82cc14235fb463ff831ef5e2c209 100644 (file)
@@ -140,7 +140,7 @@ namespace {
 
     void emitMiscInstruction(const MachineInstr &MI);
 
-    void emitNEONGetLaneInstruction(const MachineInstr &MI);
+    void emitNEONLaneInstruction(const MachineInstr &MI);
     void emitNEON1RegModImmInstruction(const MachineInstr &MI);
     void emitNEON2RegInstruction(const MachineInstr &MI);
     void emitNEON3RegInstruction(const MachineInstr &MI);
@@ -417,7 +417,8 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
     break;
   // NEON instructions.
   case ARMII::NGetLnFrm:
-    emitNEONGetLaneInstruction(MI);
+  case ARMII::NSetLnFrm:
+    emitNEONLaneInstruction(MI);
     break;
   case ARMII::N1RegModImmFrm:
     emitNEON1RegModImmInstruction(MI);
@@ -1596,16 +1597,28 @@ static unsigned convertNEONDataProcToThumb(unsigned Binary) {
   return 0xef000000 | (UBit << 28) | (Binary & 0xffffff);
 }
 
-void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
+void ARMCodeEmitter::emitNEONLaneInstruction(const MachineInstr &MI) {
   unsigned Binary = getBinaryCodeForInstr(MI);
 
+  unsigned RegTOpIdx, RegNOpIdx, LnOpIdx;
+  const TargetInstrDesc &TID = MI.getDesc();
+  if ((TID.TSFlags & ARMII::FormMask) == ARMII::NGetLnFrm) {
+    RegTOpIdx = 0;
+    RegNOpIdx = 1;
+    LnOpIdx = 2;
+  } else { // ARMII::NSetLnFrm
+    RegTOpIdx = 2;
+    RegNOpIdx = 0;
+    LnOpIdx = 3;
+  }
+
   // Set the conditional execution predicate
   Binary |= (IsThumb ? ARMCC::AL : II->getPredicate(&MI)) << ARMII::CondShift;
 
-  unsigned RegT = MI.getOperand(0).getReg();
+  unsigned RegT = MI.getOperand(RegTOpIdx).getReg();
   RegT = ARMRegisterInfo::getRegisterNumbering(RegT);
   Binary |= (RegT << ARMII::RegRdShift);
-  Binary |= encodeNEONRn(MI, 1);
+  Binary |= encodeNEONRn(MI, RegNOpIdx);
 
   unsigned LaneShift;
   if ((Binary & (1 << 22)) != 0)
@@ -1615,7 +1628,7 @@ void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
   else
     LaneShift = 2; // 32-bit elements
 
-  unsigned Lane = MI.getOperand(2).getImm() << LaneShift;
+  unsigned Lane = MI.getOperand(LnOpIdx).getImm() << LaneShift;
   unsigned Opc1 = Lane >> 2;
   unsigned Opc2 = Lane & 3;
   assert((Opc1 & 3) == 0 && "out-of-range lane number operand");