Add DecodeShuffle shuffle support for VPERMIPD variantes

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136452 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes
2011-07-29 01:31:11 +00:00
parent e89c7d4ce3
commit 2eb4c2bcad
4 changed files with 62 additions and 31 deletions

View File

@@ -205,13 +205,22 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
DecodeUNPCKHPMask(4, ShuffleMask); DecodeUNPCKHPMask(4, ShuffleMask);
Src1Name = getRegName(MI->getOperand(0).getReg()); Src1Name = getRegName(MI->getOperand(0).getReg());
break; break;
case X86::VPERMILPSri:
DecodeVPERMILPSMask(4, MI->getOperand(2).getImm(),
ShuffleMask);
Src1Name = getRegName(MI->getOperand(0).getReg());
case X86::VPERMILPSYri: case X86::VPERMILPSYri:
DecodeVPERMILPSMask(8, MI->getOperand(2).getImm(), DecodeVPERMILPSMask(8, MI->getOperand(2).getImm(),
ShuffleMask); ShuffleMask);
Src1Name = getRegName(MI->getOperand(0).getReg()); Src1Name = getRegName(MI->getOperand(0).getReg());
break; break;
case X86::VPERMILPDri:
DecodeVPERMILPDMask(2, MI->getOperand(2).getImm(),
ShuffleMask);
Src1Name = getRegName(MI->getOperand(0).getReg());
break;
case X86::VPERMILPDYri: case X86::VPERMILPDYri:
DecodeVPERMILPSMask(4, MI->getOperand(2).getImm(), DecodeVPERMILPDMask(4, MI->getOperand(2).getImm(),
ShuffleMask); ShuffleMask);
Src1Name = getRegName(MI->getOperand(0).getReg()); Src1Name = getRegName(MI->getOperand(0).getReg());
break; break;

View File

@@ -186,29 +186,36 @@ void DecodeUNPCKLPMask(EVT VT,
} }
} }
void DecodeVPERMILPSMask(unsigned NElts, unsigned Imm, // DecodeVPERMILPSMask - Decodes VPERMILPS permutes for any 128-bit 32-bit
SmallVectorImpl<unsigned> &ShuffleMask) { // elements. For 256-bit vectors, it's considered as two 128 lanes, the
DecodeVPERMILMask(MVT::getVectorVT(MVT::i32, NElts), Imm, ShuffleMask); // referenced elements can't cross lanes and the mask of the first lane must
} // be the same of the second.
void DecodeVPERMILPSMask(unsigned NumElts, unsigned Imm,
void DecodeVPERMILPDMask(unsigned NElts, unsigned Imm, SmallVectorImpl<unsigned> &ShuffleMask) {
SmallVectorImpl<unsigned> &ShuffleMask) { unsigned NumLanes = (NumElts*32)/128;
DecodeVPERMILMask(MVT::getVectorVT(MVT::i64, NElts), Imm, ShuffleMask); unsigned LaneSize = NumElts/NumLanes;
}
// DecodeVPERMILMask - Decodes VPERMIL permutes for any 128-bit
// with 32/64-bit elements. For 256-bit vectors, it's considered
// as two 128 lanes and the mask of the first lane should be
// identical of the second one.
void DecodeVPERMILMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned NumElts = VT.getVectorNumElements();
unsigned NumLanes = VT.getSizeInBits()/128;
for (unsigned l = 0; l != NumLanes; ++l) { for (unsigned l = 0; l != NumLanes; ++l) {
for (unsigned i = 0; i != NumElts/NumLanes; ++i) { for (unsigned i = 0; i != LaneSize; ++i) {
unsigned Idx = (Imm >> (i*2)) & 0x3 ; unsigned Idx = (Imm >> (i*2)) & 0x3 ;
ShuffleMask.push_back(Idx+(l*NumElts/NumLanes)); ShuffleMask.push_back(Idx+(l*LaneSize));
}
}
}
// DecodeVPERMILPDMask - Decodes VPERMILPD permutes for any 128-bit 64-bit
// elements. For 256-bit vectors, it's considered as two 128 lanes, the
// referenced elements can't cross lanes but the mask of the first lane can
// be the different of the second (not like VPERMILPS).
void DecodeVPERMILPDMask(unsigned NumElts, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned NumLanes = (NumElts*64)/128;
unsigned LaneSize = NumElts/NumLanes;
for (unsigned l = 0; l < NumLanes; ++l) {
for (unsigned i = l*LaneSize; i < LaneSize*(l+1); ++i) {
unsigned Idx = (Imm >> i) & 0x1;
ShuffleMask.push_back(Idx+(l*LaneSize));
} }
} }
} }

View File

@@ -83,19 +83,20 @@ void DecodeUNPCKLPMask(EVT VT,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
// DecodeVPERMILPSMask - Decodes VPERMILPS permutes for any 128-bit 32-bit
// elements. For 256-bit vectors, it's considered as two 128 lanes, the
// referenced elements can't cross lanes and the mask of the first lane must
// be the same of the second.
void DecodeVPERMILPSMask(unsigned NElts, unsigned Imm, void DecodeVPERMILPSMask(unsigned NElts, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
// DecodeVPERMILPDMask - Decodes VPERMILPD permutes for any 128-bit 64-bit
// elements. For 256-bit vectors, it's considered as two 128 lanes, the
// referenced elements can't cross lanes but the mask of the first lane can
// be the different of the second (not like VPERMILPS).
void DecodeVPERMILPDMask(unsigned NElts, unsigned Imm, void DecodeVPERMILPDMask(unsigned NElts, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
// DecodeVPERMILMask - Decodes VPERMIL permutes for any 128-bit
// with 32/64-bit elements. For 256-bit vectors, it's considered
// as two 128 lanes and the mask of the first lane should be
// identical of the second one.
void DecodeVPERMILMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask);
} // llvm namespace } // llvm namespace
#endif #endif

View File

@@ -4236,11 +4236,25 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
Depth+1); Depth+1);
} }
case X86ISD::VPERMILPS: case X86ISD::VPERMILPS:
case X86ISD::VPERMILPSY:
// FIXME: Implement the other types
ImmN = N->getOperand(N->getNumOperands()-1); ImmN = N->getOperand(N->getNumOperands()-1);
DecodeVPERMILMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), DecodeVPERMILPSMask(4, cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask); ShuffleMask);
break;
case X86ISD::VPERMILPSY:
ImmN = N->getOperand(N->getNumOperands()-1);
DecodeVPERMILPSMask(8, cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask);
break;
case X86ISD::VPERMILPD:
ImmN = N->getOperand(N->getNumOperands()-1);
DecodeVPERMILPDMask(2, cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask);
break;
case X86ISD::VPERMILPDY:
ImmN = N->getOperand(N->getNumOperands()-1);
DecodeVPERMILPDMask(4, cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask);
break;
default: default:
assert("not implemented for target shuffle node"); assert("not implemented for target shuffle node");
return SDValue(); return SDValue();