mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-30 17:33:24 +00:00
Pattern match vmrg* instructions, which are now lowered by the CFE into shuffles.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27457 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
91ded08224
commit
116cc48e30
@ -293,10 +293,50 @@ bool PPC::isVPKUWUMShuffleMask(SDNode *N) {
|
|||||||
return true;
|
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
|
/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
|
||||||
/// amount, otherwise return -1.
|
/// amount, otherwise return -1.
|
||||||
int PPC::isVSLDOIShuffleMask(SDNode *N) {
|
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.
|
// Find the first non-undef value in the shuffle mask.
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++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 &&
|
if (V2.getOpcode() == ISD::UNDEF &&
|
||||||
(PPC::isSplatShuffleMask(PermMask.Val, 1) ||
|
(PPC::isSplatShuffleMask(PermMask.Val, 1) ||
|
||||||
PPC::isSplatShuffleMask(PermMask.Val, 2) ||
|
PPC::isSplatShuffleMask(PermMask.Val, 2) ||
|
||||||
PPC::isSplatShuffleMask(PermMask.Val, 4)))
|
PPC::isSplatShuffleMask(PermMask.Val, 4) ||
|
||||||
|
PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1))
|
||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
if (PPC::isVPKUWUMShuffleMask(PermMask.Val) ||
|
if (PPC::isVPKUWUMShuffleMask(PermMask.Val) ||
|
||||||
PPC::isVPKUHUMShuffleMask(PermMask.Val) ||
|
PPC::isVPKUHUMShuffleMask(PermMask.Val) ||
|
||||||
PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 ||
|
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;
|
return Op;
|
||||||
|
|
||||||
// TODO: Handle more cases, and also handle cases that are cheaper to do as
|
// TODO: Handle more cases, and also handle cases that are cheaper to do as
|
||||||
|
@ -110,6 +110,14 @@ namespace llvm {
|
|||||||
/// VPKUWUM instruction.
|
/// VPKUWUM instruction.
|
||||||
bool isVPKUWUMShuffleMask(SDNode *N);
|
bool isVPKUWUMShuffleMask(SDNode *N);
|
||||||
|
|
||||||
|
/// 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 isVMRGLShuffleMask(SDNode *N, unsigned UnitSize);
|
||||||
|
|
||||||
|
/// 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 isVMRGHShuffleMask(SDNode *N, unsigned UnitSize);
|
||||||
|
|
||||||
/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
|
/// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
|
||||||
/// amount, otherwise return -1.
|
/// amount, otherwise return -1.
|
||||||
int isVSLDOIShuffleMask(SDNode *N);
|
int isVSLDOIShuffleMask(SDNode *N);
|
||||||
|
@ -24,6 +24,26 @@ def VPKUWUM_shuffle_mask : PatLeaf<(build_vector), [{
|
|||||||
return PPC::isVPKUWUMShuffleMask(N);
|
return PPC::isVPKUWUMShuffleMask(N);
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
|
def VMRGLB_shuffle_mask : PatLeaf<(build_vector), [{
|
||||||
|
return PPC::isVMRGLShuffleMask(N, 1);
|
||||||
|
}]>;
|
||||||
|
def VMRGLH_shuffle_mask : PatLeaf<(build_vector), [{
|
||||||
|
return PPC::isVMRGLShuffleMask(N, 2);
|
||||||
|
}]>;
|
||||||
|
def VMRGLW_shuffle_mask : PatLeaf<(build_vector), [{
|
||||||
|
return PPC::isVMRGLShuffleMask(N, 4);
|
||||||
|
}]>;
|
||||||
|
def VMRGHB_shuffle_mask : PatLeaf<(build_vector), [{
|
||||||
|
return PPC::isVMRGHShuffleMask(N, 1);
|
||||||
|
}]>;
|
||||||
|
def VMRGHH_shuffle_mask : PatLeaf<(build_vector), [{
|
||||||
|
return PPC::isVMRGHShuffleMask(N, 2);
|
||||||
|
}]>;
|
||||||
|
def VMRGHW_shuffle_mask : PatLeaf<(build_vector), [{
|
||||||
|
return PPC::isVMRGHShuffleMask(N, 4);
|
||||||
|
}]>;
|
||||||
|
|
||||||
|
|
||||||
def VSLDOI_get_imm : SDNodeXForm<build_vector, [{
|
def VSLDOI_get_imm : SDNodeXForm<build_vector, [{
|
||||||
return getI32Imm(PPC::isVSLDOIShuffleMask(N));
|
return getI32Imm(PPC::isVSLDOIShuffleMask(N));
|
||||||
}]>;
|
}]>;
|
||||||
@ -278,12 +298,30 @@ def VMINUB : VX1_Int< 514, "vminub", int_ppc_altivec_vminub>;
|
|||||||
def VMINUH : VX1_Int< 578, "vminuh", int_ppc_altivec_vminuh>;
|
def VMINUH : VX1_Int< 578, "vminuh", int_ppc_altivec_vminuh>;
|
||||||
def VMINUW : VX1_Int< 642, "vminuw", int_ppc_altivec_vminuw>;
|
def VMINUW : VX1_Int< 642, "vminuw", int_ppc_altivec_vminuw>;
|
||||||
|
|
||||||
def VMRGHB : VX1_Int<12 , "vmrghb", int_ppc_altivec_vmrghb>;
|
def VMRGHB : VXForm_1< 12, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
|
||||||
def VMRGHH : VX1_Int<76 , "vmrghh", int_ppc_altivec_vmrghh>;
|
"vmrghb $vD, $vA, $vB", VecFP,
|
||||||
def VMRGHW : VX1_Int<140, "vmrghw", int_ppc_altivec_vmrghw>;
|
[(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
|
||||||
def VMRGLB : VX1_Int<268, "vmrglb", int_ppc_altivec_vmrglb>;
|
VRRC:$vB, VMRGHB_shuffle_mask))]>;
|
||||||
def VMRGLH : VX1_Int<332, "vmrglh", int_ppc_altivec_vmrglh>;
|
def VMRGHH : VXForm_1< 76, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
|
||||||
def VMRGLW : VX1_Int<396, "vmrglw", int_ppc_altivec_vmrglw>;
|
"vmrghh $vD, $vA, $vB", VecFP,
|
||||||
|
[(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
|
||||||
|
VRRC:$vB, VMRGHH_shuffle_mask))]>;
|
||||||
|
def VMRGHW : VXForm_1<140, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
|
||||||
|
"vmrghw $vD, $vA, $vB", VecFP,
|
||||||
|
[(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
|
||||||
|
VRRC:$vB, VMRGHW_shuffle_mask))]>;
|
||||||
|
def VMRGLB : VXForm_1<268, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
|
||||||
|
"vmrglb $vD, $vA, $vB", VecFP,
|
||||||
|
[(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
|
||||||
|
VRRC:$vB, VMRGLB_shuffle_mask))]>;
|
||||||
|
def VMRGLH : VXForm_1<332, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
|
||||||
|
"vmrglh $vD, $vA, $vB", VecFP,
|
||||||
|
[(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
|
||||||
|
VRRC:$vB, VMRGLH_shuffle_mask))]>;
|
||||||
|
def VMRGLW : VXForm_1<396, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
|
||||||
|
"vmrglw $vD, $vA, $vB", VecFP,
|
||||||
|
[(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
|
||||||
|
VRRC:$vB, VMRGLW_shuffle_mask))]>;
|
||||||
|
|
||||||
def VMSUMMBM : VA1a_Int<37, "vmsummbm", int_ppc_altivec_vmsummbm>;
|
def VMSUMMBM : VA1a_Int<37, "vmsummbm", int_ppc_altivec_vmsummbm>;
|
||||||
def VMSUMSHM : VA1a_Int<40, "vmsumshm", int_ppc_altivec_vmsumshm>;
|
def VMSUMSHM : VA1a_Int<40, "vmsumshm", int_ppc_altivec_vmsumshm>;
|
||||||
|
@ -129,6 +129,3 @@ void test(vector int *X, vector int *Y) {
|
|||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
Lower "merges" in the front-end to shuffles, reconstruct in the backend.
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
Loading…
Reference in New Issue
Block a user