[llvm-commits] [llvm] r108227 - in /llvm/trunk/lib/Target/ARM: ARMAddressingModes.h ARMISelLowering.cpp AsmPrinter/ARMAsmPrinter.cpp AsmPrinter/ARMInstPrinter.cpp

Bob Wilson bob.wilson at apple.com
Mon Jul 12 21:44:35 PDT 2010


Author: bwilson
Date: Mon Jul 12 23:44:34 2010
New Revision: 108227

URL: http://llvm.org/viewvc/llvm-project?rev=108227&view=rev
Log:
Move NEON "modified immediate" encode/decode into ARMAddressingModes.h to
avoid replicated code.

Modified:
    llvm/trunk/lib/Target/ARM/ARMAddressingModes.h
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
    llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMAddressingModes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAddressingModes.h?rev=108227&r1=108226&r2=108227&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAddressingModes.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMAddressingModes.h Mon Jul 12 23:44:34 2010
@@ -523,6 +523,68 @@
   // Valid alignments are: 0, 8, 16, and 32 bytes, depending on the specific
   // instruction.
 
+  //===--------------------------------------------------------------------===//
+  // NEON Modified Immediates
+  //===--------------------------------------------------------------------===//
+  //
+  // Several NEON instructions (e.g., VMOV) take a "modified immediate"
+  // vector operand, where a small immediate encoded in the instruction
+  // specifies a full NEON vector value.  These modified immediates are
+  // represented here as encoded integers.  The low 8 bits hold the immediate
+  // value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
+  // the "Cmode" field of the instruction.  The interfaces below treat the
+  // Op and Cmode values as a single 5-bit value.
+
+  static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val) {
+    return (OpCmode << 8) | Val;
+  }
+  static inline unsigned getNEONModImmOpCmode(unsigned ModImm) {
+    return (ModImm >> 8) & 0x1f;
+  }
+  static inline unsigned getNEONModImmVal(unsigned ModImm) {
+    return ModImm & 0xff;
+  }
+
+  /// decodeNEONModImm - Decode a NEON modified immediate value into the
+  /// element value and the element size in bits.  (If the element size is
+  /// smaller than the vector, it is splatted into all the elements.)
+  static inline uint64_t decodeNEONModImm(unsigned ModImm, unsigned &EltBits) {
+    unsigned OpCmode = getNEONModImmOpCmode(ModImm);
+    unsigned Imm8 = getNEONModImmVal(ModImm);
+    uint64_t Val = 0;
+
+    if (OpCmode == 0xe) {
+      // 8-bit vector elements
+      Val = Imm8;
+      EltBits = 8;
+    } else if ((OpCmode & 0xc) == 0x8) {
+      // 16-bit vector elements
+      unsigned ByteNum = (OpCmode & 0x6) >> 1;
+      Val = Imm8 << (8 * ByteNum);
+      EltBits = 16;
+    } else if ((OpCmode & 0x8) == 0) {
+      // 32-bit vector elements, zero with one byte set
+      unsigned ByteNum = (OpCmode & 0x6) >> 1;
+      Val = Imm8 << (8 * ByteNum);
+      EltBits = 32;
+    } else if ((OpCmode & 0xe) == 0xc) {
+      // 32-bit vector elements, one byte with low bits set
+      unsigned ByteNum = 1 + (OpCmode & 0x1);
+      Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
+      EltBits = 32;
+    } else if (OpCmode == 0x1e) {
+      // 64-bit vector elements
+      for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
+        if ((ModImm >> ByteNum) & 1)
+          Val |= (uint64_t)0xff << (8 * ByteNum);
+      }
+      EltBits = 64;
+    } else {
+      assert(false && "Unsupported NEON immediate");
+    }
+    return Val;
+  }
+
 } // end namespace ARM_AM
 } // end namespace llvm
 

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=108227&r1=108226&r2=108227&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Jul 12 23:44:34 2010
@@ -2851,13 +2851,11 @@
 /// isNEONModifiedImm - Check if the specified splat value corresponds to a
 /// valid vector constant for a NEON instruction with a "modified immediate"
 /// operand (e.g., VMOV).  If so, return either the constant being
-/// splatted or the encoded value, depending on the DoEncode parameter.  The
-/// format of the encoded value is: bit12=Op, bits11-8=Cmode,
-/// bits7-0=Immediate.
+/// splatted or the encoded value, depending on the DoEncode parameter.
 static SDValue isNEONModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
                                  unsigned SplatBitSize, SelectionDAG &DAG,
                                  bool isVMOV, bool DoEncode) {
-  unsigned Op, Cmode, Imm;
+  unsigned OpCmode, Imm;
   EVT VT;
 
   // SplatBitSize is set to the smallest size that splats the vector, so a
@@ -2868,12 +2866,11 @@
   if (SplatBits == 0)
     SplatBitSize = 32;
 
-  Op = 0;
   switch (SplatBitSize) {
   case 8:
     // Any 1-byte value is OK.  Op=0, Cmode=1110.
     assert((SplatBits & ~0xff) == 0 && "one byte splat value is too big");
-    Cmode = 0xe;
+    OpCmode = 0xe;
     Imm = SplatBits;
     VT = MVT::i8;
     break;
@@ -2883,13 +2880,13 @@
     VT = MVT::i16;
     if ((SplatBits & ~0xff) == 0) {
       // Value = 0x00nn: Op=x, Cmode=100x.
-      Cmode = 0x8;
+      OpCmode = 0x8;
       Imm = SplatBits;
       break;
     }
     if ((SplatBits & ~0xff00) == 0) {
       // Value = 0xnn00: Op=x, Cmode=101x.
-      Cmode = 0xa;
+      OpCmode = 0xa;
       Imm = SplatBits >> 8;
       break;
     }
@@ -2903,25 +2900,25 @@
     VT = MVT::i32;
     if ((SplatBits & ~0xff) == 0) {
       // Value = 0x000000nn: Op=x, Cmode=000x.
-      Cmode = 0;
+      OpCmode = 0;
       Imm = SplatBits;
       break;
     }
     if ((SplatBits & ~0xff00) == 0) {
       // Value = 0x0000nn00: Op=x, Cmode=001x.
-      Cmode = 0x2;
+      OpCmode = 0x2;
       Imm = SplatBits >> 8;
       break;
     }
     if ((SplatBits & ~0xff0000) == 0) {
       // Value = 0x00nn0000: Op=x, Cmode=010x.
-      Cmode = 0x4;
+      OpCmode = 0x4;
       Imm = SplatBits >> 16;
       break;
     }
     if ((SplatBits & ~0xff000000) == 0) {
       // Value = 0xnn000000: Op=x, Cmode=011x.
-      Cmode = 0x6;
+      OpCmode = 0x6;
       Imm = SplatBits >> 24;
       break;
     }
@@ -2929,7 +2926,7 @@
     if ((SplatBits & ~0xffff) == 0 &&
         ((SplatBits | SplatUndef) & 0xff) == 0xff) {
       // Value = 0x0000nnff: Op=x, Cmode=1100.
-      Cmode = 0xc;
+      OpCmode = 0xc;
       Imm = SplatBits >> 8;
       SplatBits |= 0xff;
       break;
@@ -2938,7 +2935,7 @@
     if ((SplatBits & ~0xffffff) == 0 &&
         ((SplatBits | SplatUndef) & 0xffff) == 0xffff) {
       // Value = 0x00nnffff: Op=x, Cmode=1101.
-      Cmode = 0xd;
+      OpCmode = 0xd;
       Imm = SplatBits >> 16;
       SplatBits |= 0xffff;
       break;
@@ -2970,8 +2967,7 @@
       ImmMask <<= 1;
     }
     // Op=1, Cmode=1110.
-    Op = 1;
-    Cmode = 0xe;
+    OpCmode = 0x1e;
     SplatBits = Val;
     VT = MVT::i64;
     break;
@@ -2982,12 +2978,13 @@
     return SDValue();
   }
 
-  if (DoEncode)
-    return DAG.getTargetConstant((Op << 12) | (Cmode << 8) | Imm, MVT::i32);
+  if (DoEncode) {
+    unsigned EncodedVal = ARM_AM::createNEONModImm(OpCmode, Imm);
+    return DAG.getTargetConstant(EncodedVal, MVT::i32);
+  }
   return DAG.getTargetConstant(SplatBits, VT);
 }
 
-
 /// getNEONModImm - If this is a valid vector constant for a NEON instruction
 /// with a "modified immediate" operand (e.g., VMOV) of the specified element
 /// size, return the encoded value for that immediate.  The ByteSize field

Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp?rev=108227&r1=108226&r2=108227&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp Mon Jul 12 23:44:34 2010
@@ -1030,35 +1030,9 @@
 
 void ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
                                            raw_ostream &O) {
-  unsigned Imm = MI->getOperand(OpNum).getImm();
-  unsigned OpCmode = (Imm >> 8) & 0x1f;
-  unsigned Imm8 = Imm & 0xff;
-  uint64_t Val = 0;
-
-  if (OpCmode == 0xe) {
-    // 8-bit vector elements
-    Val = Imm8;
-  } else if ((OpCmode & 0xc) == 0x8) {
-    // 16-bit vector elements
-    unsigned ByteNum = (OpCmode & 0x6) >> 1;
-    Val = Imm8 << (8 * ByteNum);
-  } else if ((OpCmode & 0x8) == 0) {
-    // 32-bit vector elements, zero with one byte set
-    unsigned ByteNum = (OpCmode & 0x6) >> 1;
-    Val = Imm8 << (8 * ByteNum);
-  } else if ((OpCmode & 0xe) == 0xc) {
-    // 32-bit vector elements, one byte with low bits set
-    unsigned ByteNum = 1 + (OpCmode & 0x1);
-    Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
-  } else if (OpCmode == 0x1e) {
-    // 64-bit vector elements
-    for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
-      if ((Imm >> ByteNum) & 1)
-        Val |= (uint64_t)0xff << (8 * ByteNum);
-    }
-  } else {
-    assert(false && "Unsupported NEON immediate");
-  }
+  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
+  unsigned EltBits;
+  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
   O << "#0x" << utohexstr(Val);
 }
 

Modified: llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp?rev=108227&r1=108226&r2=108227&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp Mon Jul 12 23:44:34 2010
@@ -781,34 +781,8 @@
 
 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
                                             raw_ostream &O) {
-  unsigned Imm = MI->getOperand(OpNum).getImm();
-  unsigned OpCmode = (Imm >> 8) & 0x1f;
-  unsigned Imm8 = Imm & 0xff;
-  uint64_t Val = 0;
-
-  if (OpCmode == 0xe) {
-    // 8-bit vector elements
-    Val = Imm8;
-  } else if ((OpCmode & 0xc) == 0x8) {
-    // 16-bit vector elements
-    unsigned ByteNum = (OpCmode & 0x6) >> 1;
-    Val = Imm8 << (8 * ByteNum);
-  } else if ((OpCmode & 0x8) == 0) {
-    // 32-bit vector elements, zero with one byte set
-    unsigned ByteNum = (OpCmode & 0x6) >> 1;
-    Val = Imm8 << (8 * ByteNum);
-  } else if ((OpCmode & 0xe) == 0xc) {
-    // 32-bit vector elements, one byte with low bits set
-    unsigned ByteNum = 1 + (OpCmode & 0x1);
-    Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
-  } else if (OpCmode == 0x1e) {
-    // 64-bit vector elements
-    for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
-      if ((Imm >> ByteNum) & 1)
-        Val |= (uint64_t)0xff << (8 * ByteNum);
-    }
-  } else {
-    assert(false && "Unsupported NEON immediate");
-  }
+  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
+  unsigned EltBits;
+  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
   O << "#0x" << utohexstr(Val);
 }





More information about the llvm-commits mailing list