Add support for encoding NEON VMOV (from scalar to core register) instructions.
authorBob Wilson <bob.wilson@apple.com>
Sat, 26 Jun 2010 04:07:15 +0000 (04:07 +0000)
committerBob Wilson <bob.wilson@apple.com>
Sat, 26 Jun 2010 04:07:15 +0000 (04:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106938 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp

index 7f3c5d80f1e55b436907fa2ba912592c3b506843..49e83c3f8a9632ed0f1ea55ea7a5327949e894de 100644 (file)
@@ -139,6 +139,7 @@ namespace {
 
     void emitMiscInstruction(const MachineInstr &MI);
 
+    void emitNEONGetLaneInstruction(const MachineInstr &MI);
     void emitNEON1RegModImmInstruction(const MachineInstr &MI);
     void emitNEON2RegInstruction(const MachineInstr &MI);
     void emitNEON3RegInstruction(const MachineInstr &MI);
@@ -413,6 +414,9 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
     emitMiscInstruction(MI);
     break;
   // NEON instructions.
+  case ARMII::NGetLnFrm:
+    emitNEONGetLaneInstruction(MI);
+    break;
   case ARMII::N1RegModImmFrm:
     emitNEON1RegModImmInstruction(MI);
     break;
@@ -1581,6 +1585,35 @@ static unsigned encodeNEONRm(const MachineInstr &MI, unsigned OpIdx) {
   return Binary;
 }
 
+void ARMCodeEmitter::emitNEONGetLaneInstruction(const MachineInstr &MI) {
+  unsigned Binary = getBinaryCodeForInstr(MI);
+
+  // Set the conditional execution predicate
+  Binary |= II->getPredicate(&MI) << ARMII::CondShift;
+
+  unsigned RegT = MI.getOperand(0).getReg();
+  RegT = ARMRegisterInfo::getRegisterNumbering(RegT);
+  Binary |= (RegT << ARMII::RegRdShift);
+  Binary |= encodeNEONRn(MI, 1);
+
+  unsigned LaneShift;
+  if ((Binary & (1 << 22)) != 0)
+    LaneShift = 0; // 8-bit elements
+  else if ((Binary & (1 << 5)) != 0)
+    LaneShift = 1; // 16-bit elements
+  else
+    LaneShift = 2; // 32-bit elements
+
+  unsigned Lane = MI.getOperand(2).getImm() << LaneShift;
+  unsigned Opc1 = Lane >> 2;
+  unsigned Opc2 = Lane & 3;
+  assert((Opc1 & 3) == 0 && "out-of-range lane number operand");
+  Binary |= (Opc1 << 21);
+  Binary |= (Opc2 << 5);
+
+  emitWordLE(Binary);
+}
+
 void ARMCodeEmitter::emitNEON1RegModImmInstruction(const MachineInstr &MI) {
   unsigned Binary = getBinaryCodeForInstr(MI);
   // Destination register is encoded in Dd.