mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Add support for selecting AVX2 vpshuflw and vpshufhw. Add decoding support for AsmPrinter.
llvm-svn: 155982
This commit is contained in:
parent
f88d204f91
commit
00ccecdc84
@ -96,7 +96,17 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||
case X86::PSHUFHWmi:
|
||||
case X86::VPSHUFHWmi:
|
||||
DestName = getRegName(MI->getOperand(0).getReg());
|
||||
DecodePSHUFHWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
|
||||
DecodePSHUFHWMask(MVT::v8i16,
|
||||
MI->getOperand(MI->getNumOperands()-1).getImm(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86::VPSHUFHWYri:
|
||||
Src1Name = getRegName(MI->getOperand(1).getReg());
|
||||
// FALL THROUGH.
|
||||
case X86::VPSHUFHWYmi:
|
||||
DestName = getRegName(MI->getOperand(0).getReg());
|
||||
DecodePSHUFHWMask(MVT::v16i16,
|
||||
MI->getOperand(MI->getNumOperands()-1).getImm(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86::PSHUFLWri:
|
||||
@ -106,7 +116,17 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||
case X86::PSHUFLWmi:
|
||||
case X86::VPSHUFLWmi:
|
||||
DestName = getRegName(MI->getOperand(0).getReg());
|
||||
DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
|
||||
DecodePSHUFLWMask(MVT::v8i16,
|
||||
MI->getOperand(MI->getNumOperands()-1).getImm(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86::VPSHUFLWYri:
|
||||
Src1Name = getRegName(MI->getOperand(1).getReg());
|
||||
// FALL THROUGH.
|
||||
case X86::VPSHUFLWYmi:
|
||||
DestName = getRegName(MI->getOperand(0).getReg());
|
||||
DecodePSHUFLWMask(MVT::v16i16,
|
||||
MI->getOperand(MI->getNumOperands()-1).getImm(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
|
||||
|
@ -70,7 +70,7 @@ void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumLanes = VT.getSizeInBits() / 128;
|
||||
unsigned NumLaneElts = NumElts / NumLanes;
|
||||
|
||||
int NewImm = Imm;
|
||||
unsigned NewImm = Imm;
|
||||
for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
|
||||
for (unsigned i = 0; i != NumLaneElts; ++i) {
|
||||
ShuffleMask.push_back(NewImm % NumLaneElts + l);
|
||||
@ -80,26 +80,38 @@ void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
}
|
||||
}
|
||||
|
||||
void DecodePSHUFHWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
ShuffleMask.push_back(0);
|
||||
ShuffleMask.push_back(1);
|
||||
ShuffleMask.push_back(2);
|
||||
ShuffleMask.push_back(3);
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
ShuffleMask.push_back(4+(Imm & 3));
|
||||
Imm >>= 2;
|
||||
void DecodePSHUFHWMask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumLanes = VT.getSizeInBits() / 128;
|
||||
unsigned NumElts = 8 * NumLanes;
|
||||
|
||||
for (unsigned l = 0; l != NumElts; l += 8) {
|
||||
unsigned NewImm = Imm;
|
||||
for (unsigned i = 0, e = 4; i != e; ++i) {
|
||||
ShuffleMask.push_back(l + i);
|
||||
}
|
||||
for (unsigned i = 4, e = 8; i != e; ++i) {
|
||||
ShuffleMask.push_back(l + 4 + (NewImm & 3));
|
||||
NewImm >>= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
ShuffleMask.push_back((Imm & 3));
|
||||
Imm >>= 2;
|
||||
void DecodePSHUFLWMask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumLanes = VT.getSizeInBits() / 128;
|
||||
unsigned NumElts = 8 * NumLanes;
|
||||
|
||||
for (unsigned l = 0; l != NumElts; l += 8) {
|
||||
unsigned NewImm = Imm;
|
||||
for (unsigned i = 0, e = 4; i != e; ++i) {
|
||||
ShuffleMask.push_back(l + (NewImm & 3));
|
||||
NewImm >>= 2;
|
||||
}
|
||||
for (unsigned i = 4, e = 8; i != e; ++i) {
|
||||
ShuffleMask.push_back(l + i);
|
||||
}
|
||||
}
|
||||
ShuffleMask.push_back(4);
|
||||
ShuffleMask.push_back(5);
|
||||
ShuffleMask.push_back(6);
|
||||
ShuffleMask.push_back(7);
|
||||
}
|
||||
|
||||
/// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates
|
||||
@ -111,7 +123,7 @@ void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumLanes = VT.getSizeInBits() / 128;
|
||||
unsigned NumLaneElts = NumElts / NumLanes;
|
||||
|
||||
int NewImm = Imm;
|
||||
unsigned NewImm = Imm;
|
||||
for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
|
||||
// Part that reads from dest.
|
||||
for (unsigned i = 0; i != NumLaneElts/2; ++i) {
|
||||
@ -176,9 +188,9 @@ void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
|
||||
unsigned FstHalfBegin = (Imm & 0x3) * HalfSize;
|
||||
unsigned SndHalfBegin = ((Imm >> 4) & 0x3) * HalfSize;
|
||||
|
||||
for (int i = FstHalfBegin, e = FstHalfBegin+HalfSize; i != e; ++i)
|
||||
for (unsigned i = FstHalfBegin, e = FstHalfBegin+HalfSize; i != e; ++i)
|
||||
ShuffleMask.push_back(i);
|
||||
for (int i = SndHalfBegin, e = SndHalfBegin+HalfSize; i != e; ++i)
|
||||
for (unsigned i = SndHalfBegin, e = SndHalfBegin+HalfSize; i != e; ++i)
|
||||
ShuffleMask.push_back(i);
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,9 @@ void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
void DecodePSHUFHWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
void DecodePSHUFHWMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
void DecodePSHUFLWMask(EVT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
/// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates
|
||||
/// the type of the vector allowing it to handle different datatypes and vector
|
||||
|
@ -3196,8 +3196,8 @@ static bool isPSHUFDMask(ArrayRef<int> Mask, EVT VT) {
|
||||
|
||||
/// isPSHUFHWMask - Return true if the node specifies a shuffle of elements that
|
||||
/// is suitable for input to PSHUFHW.
|
||||
static bool isPSHUFHWMask(ArrayRef<int> Mask, EVT VT) {
|
||||
if (VT != MVT::v8i16)
|
||||
static bool isPSHUFHWMask(ArrayRef<int> Mask, EVT VT, bool HasAVX2) {
|
||||
if (VT != MVT::v8i16 && (!HasAVX2 || VT != MVT::v16i16))
|
||||
return false;
|
||||
|
||||
// Lower quadword copied in order or undef.
|
||||
@ -3206,16 +3206,27 @@ static bool isPSHUFHWMask(ArrayRef<int> Mask, EVT VT) {
|
||||
|
||||
// Upper quadword shuffled.
|
||||
for (unsigned i = 4; i != 8; ++i)
|
||||
if (Mask[i] >= 0 && (Mask[i] < 4 || Mask[i] > 7))
|
||||
if (!isUndefOrInRange(Mask[i], 4, 8))
|
||||
return false;
|
||||
|
||||
if (VT == MVT::v16i16) {
|
||||
// Lower quadword copied in order or undef.
|
||||
if (!isSequentialOrUndefInRange(Mask, 8, 4, 8))
|
||||
return false;
|
||||
|
||||
// Upper quadword shuffled.
|
||||
for (unsigned i = 12; i != 16; ++i)
|
||||
if (!isUndefOrInRange(Mask[i], 12, 16))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// isPSHUFLWMask - Return true if the node specifies a shuffle of elements that
|
||||
/// is suitable for input to PSHUFLW.
|
||||
static bool isPSHUFLWMask(ArrayRef<int> Mask, EVT VT) {
|
||||
if (VT != MVT::v8i16)
|
||||
static bool isPSHUFLWMask(ArrayRef<int> Mask, EVT VT, bool HasAVX2) {
|
||||
if (VT != MVT::v8i16 && (!HasAVX2 || VT != MVT::v16i16))
|
||||
return false;
|
||||
|
||||
// Upper quadword copied in order.
|
||||
@ -3224,9 +3235,20 @@ static bool isPSHUFLWMask(ArrayRef<int> Mask, EVT VT) {
|
||||
|
||||
// Lower quadword shuffled.
|
||||
for (unsigned i = 0; i != 4; ++i)
|
||||
if (Mask[i] >= 4)
|
||||
if (!isUndefOrInRange(Mask[i], 0, 4))
|
||||
return false;
|
||||
|
||||
if (VT == MVT::v16i16) {
|
||||
// Upper quadword copied in order.
|
||||
if (!isSequentialOrUndefInRange(Mask, 12, 4, 12))
|
||||
return false;
|
||||
|
||||
// Lower quadword shuffled.
|
||||
for (unsigned i = 8; i != 12; ++i)
|
||||
if (!isUndefOrInRange(Mask[i], 8, 12))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4405,12 +4427,12 @@ static bool getTargetShuffleMask(SDNode *N, EVT VT,
|
||||
break;
|
||||
case X86ISD::PSHUFHW:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFHWMask(cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
DecodePSHUFHWMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
IsUnary = true;
|
||||
break;
|
||||
case X86ISD::PSHUFLW:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFLWMask(cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
DecodePSHUFLWMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
IsUnary = true;
|
||||
break;
|
||||
case X86ISD::MOVSS:
|
||||
@ -6581,12 +6603,12 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const {
|
||||
return getTargetShuffleNode(X86ISD::UNPCKL, dl, VT, V1, V1, DAG);
|
||||
}
|
||||
|
||||
if (isPSHUFHWMask(M, VT))
|
||||
if (isPSHUFHWMask(M, VT, HasAVX2))
|
||||
return getTargetShuffleNode(X86ISD::PSHUFHW, dl, VT, V1,
|
||||
getShufflePSHUFHWImmediate(SVOp),
|
||||
DAG);
|
||||
|
||||
if (isPSHUFLWMask(M, VT))
|
||||
if (isPSHUFLWMask(M, VT, HasAVX2))
|
||||
return getTargetShuffleNode(X86ISD::PSHUFLW, dl, VT, V1,
|
||||
getShufflePSHUFLWImmediate(SVOp),
|
||||
DAG);
|
||||
@ -11376,8 +11398,8 @@ X86TargetLowering::isShuffleMaskLegal(const SmallVectorImpl<int> &M,
|
||||
isMOVLMask(M, VT) ||
|
||||
isSHUFPMask(M, VT, Subtarget->hasAVX()) ||
|
||||
isPSHUFDMask(M, VT) ||
|
||||
isPSHUFHWMask(M, VT) ||
|
||||
isPSHUFLWMask(M, VT) ||
|
||||
isPSHUFHWMask(M, VT, Subtarget->hasAVX2()) ||
|
||||
isPSHUFLWMask(M, VT, Subtarget->hasAVX2()) ||
|
||||
isPALIGNRMask(M, VT, Subtarget) ||
|
||||
isUNPCKLMask(M, VT, Subtarget->hasAVX2()) ||
|
||||
isUNPCKHMask(M, VT, Subtarget->hasAVX2()) ||
|
||||
|
@ -12,3 +12,17 @@ define <16 x i16> @blendw1(<16 x i16> %a, <16 x i16> %b) nounwind alwaysinline {
|
||||
%t = shufflevector <16 x i16> %a, <16 x i16> %b, <16 x i32> <i32 0, i32 17, i32 18, i32 3, i32 20, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 31>
|
||||
ret <16 x i16> %t
|
||||
}
|
||||
|
||||
; CHECK: vpshufhw $27, %ymm
|
||||
define <16 x i16> @vpshufhw(<16 x i16> %src1) nounwind uwtable readnone ssp {
|
||||
entry:
|
||||
%shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src1, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 7, i32 6, i32 5, i32 4, i32 8, i32 9, i32 10, i32 11, i32 15, i32 14, i32 13, i32 12>
|
||||
ret <16 x i16> %shuffle.i
|
||||
}
|
||||
|
||||
; CHECK: vpshuflw $27, %ymm
|
||||
define <16 x i16> @vpshuflw(<16 x i16> %src1) nounwind uwtable readnone ssp {
|
||||
entry:
|
||||
%shuffle.i = shufflevector <16 x i16> %src1, <16 x i16> %src1, <16 x i32> <i32 3, i32 2, i32 1, i32 0, i32 4, i32 5, i32 6, i32 7, i32 11, i32 10, i32 9, i32 8, i32 12, i32 13, i32 14, i32 15>
|
||||
ret <16 x i16> %shuffle.i
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user