[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