summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-04-06 21:11:54 +0000
committerChris Lattner <sabre@nondot.org>2006-04-06 21:11:54 +0000
commitd1dcb52093312d276a4e8a902ff4288f6e684929 (patch)
treee9ec6bec07a025ae2c694a38377540977ef11665 /llvm/lib/Target/PowerPC/PPCISelLowering.cpp
parent726df0bb825bf4c3e81b0aecb8dc48810ba85dc4 (diff)
downloadbcm5719-llvm-d1dcb52093312d276a4e8a902ff4288f6e684929.tar.gz
bcm5719-llvm-d1dcb52093312d276a4e8a902ff4288f6e684929.zip
Pattern match vmrg* instructions, which are now lowered by the CFE into shuffles.
llvm-svn: 27457
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCISelLowering.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index c954f8ced8d..53c3cee5628 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -293,10 +293,50 @@ bool PPC::isVPKUWUMShuffleMask(SDNode *N) {
return true;
}
+/// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
+/// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
+bool PPC::isVMRGLShuffleMask(SDNode *N, unsigned UnitSize) {
+ assert(N->getOpcode() == ISD::BUILD_VECTOR &&
+ N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
+ assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
+ "Unsupported merge size!");
+
+ for (unsigned i = 0; i != 8/UnitSize; ++i) // Step over units
+ for (unsigned j = 0; j != UnitSize; ++j) { // Step over bytes within unit
+ if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j),
+ 8+j+i*UnitSize) ||
+ !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j),
+ 24+j+i*UnitSize))
+ return false;
+ }
+ return true;
+}
+
+/// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
+/// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).
+bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize) {
+ assert(N->getOpcode() == ISD::BUILD_VECTOR &&
+ N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
+ assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
+ "Unsupported merge size!");
+
+ for (unsigned i = 0; i != 8/UnitSize; ++i) // Step over units
+ for (unsigned j = 0; j != UnitSize; ++j) { // Step over bytes within unit
+ if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j),
+ 0+j+i*UnitSize) ||
+ !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j),
+ 16+j+i*UnitSize))
+ return false;
+ }
+ return true;
+}
+
+
/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
/// amount, otherwise return -1.
int PPC::isVSLDOIShuffleMask(SDNode *N) {
- assert(N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
+ assert(N->getOpcode() == ISD::BUILD_VECTOR &&
+ N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
// Find the first non-undef value in the shuffle mask.
unsigned i;
for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++i)
@@ -833,13 +873,19 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
if (V2.getOpcode() == ISD::UNDEF &&
(PPC::isSplatShuffleMask(PermMask.Val, 1) ||
PPC::isSplatShuffleMask(PermMask.Val, 2) ||
- PPC::isSplatShuffleMask(PermMask.Val, 4)))
+ PPC::isSplatShuffleMask(PermMask.Val, 4) ||
+ PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1))
return Op;
if (PPC::isVPKUWUMShuffleMask(PermMask.Val) ||
PPC::isVPKUHUMShuffleMask(PermMask.Val) ||
PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 ||
- PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1)
+ PPC::isVMRGLShuffleMask(PermMask.Val, 1) ||
+ PPC::isVMRGLShuffleMask(PermMask.Val, 2) ||
+ PPC::isVMRGLShuffleMask(PermMask.Val, 4) ||
+ PPC::isVMRGHShuffleMask(PermMask.Val, 1) ||
+ PPC::isVMRGHShuffleMask(PermMask.Val, 2) ||
+ PPC::isVMRGHShuffleMask(PermMask.Val, 4))
return Op;
// TODO: Handle more cases, and also handle cases that are cheaper to do as
OpenPOWER on IntegriCloud