mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	Recognize Neon VREV shuffles during legalization instead of selection.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78850 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		@@ -484,6 +484,9 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
 | 
				
			|||||||
  case ARMISD::VST2D:         return "ARMISD::VST2D";
 | 
					  case ARMISD::VST2D:         return "ARMISD::VST2D";
 | 
				
			||||||
  case ARMISD::VST3D:         return "ARMISD::VST3D";
 | 
					  case ARMISD::VST3D:         return "ARMISD::VST3D";
 | 
				
			||||||
  case ARMISD::VST4D:         return "ARMISD::VST4D";
 | 
					  case ARMISD::VST4D:         return "ARMISD::VST4D";
 | 
				
			||||||
 | 
					  case ARMISD::VREV64:        return "ARMISD::VREV64";
 | 
				
			||||||
 | 
					  case ARMISD::VREV32:        return "ARMISD::VREV32";
 | 
				
			||||||
 | 
					  case ARMISD::VREV16:        return "ARMISD::VREV16";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2336,7 +2339,7 @@ SDValue ARM::getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
 | 
				
			|||||||
/// isVREVMask - Check if a vector shuffle corresponds to a VREV
 | 
					/// isVREVMask - Check if a vector shuffle corresponds to a VREV
 | 
				
			||||||
/// instruction with the specified blocksize.  (The order of the elements
 | 
					/// instruction with the specified blocksize.  (The order of the elements
 | 
				
			||||||
/// within each block of the vector is reversed.)
 | 
					/// within each block of the vector is reversed.)
 | 
				
			||||||
bool ARM::isVREVMask(ShuffleVectorSDNode *N, unsigned BlockSize) {
 | 
					static bool isVREVMask(ShuffleVectorSDNode *N, unsigned BlockSize) {
 | 
				
			||||||
  assert((BlockSize==16 || BlockSize==32 || BlockSize==64) &&
 | 
					  assert((BlockSize==16 || BlockSize==32 || BlockSize==64) &&
 | 
				
			||||||
         "Only possible block sizes for VREV are: 16, 32, 64");
 | 
					         "Only possible block sizes for VREV are: 16, 32, 64");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2432,6 +2435,18 @@ static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
 | 
					static SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
 | 
				
			||||||
 | 
					  ShuffleVectorSDNode *SVN = dyn_cast<ShuffleVectorSDNode>(Op.getNode());
 | 
				
			||||||
 | 
					  assert(SVN != 0 && "Expected a ShuffleVectorSDNode in LowerVECTOR_SHUFFLE");
 | 
				
			||||||
 | 
					  DebugLoc dl = Op.getDebugLoc();
 | 
				
			||||||
 | 
					  EVT VT = Op.getValueType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (isVREVMask(SVN, 64))
 | 
				
			||||||
 | 
					    return DAG.getNode(ARMISD::VREV64, dl, VT, SVN->getOperand(0));
 | 
				
			||||||
 | 
					  if (isVREVMask(SVN, 32))
 | 
				
			||||||
 | 
					    return DAG.getNode(ARMISD::VREV32, dl, VT, SVN->getOperand(0));
 | 
				
			||||||
 | 
					  if (isVREVMask(SVN, 16))
 | 
				
			||||||
 | 
					    return DAG.getNode(ARMISD::VREV16, dl, VT, SVN->getOperand(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Op;
 | 
					  return Op;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -124,7 +124,12 @@ namespace llvm {
 | 
				
			|||||||
      VLD4D,
 | 
					      VLD4D,
 | 
				
			||||||
      VST2D,
 | 
					      VST2D,
 | 
				
			||||||
      VST3D,
 | 
					      VST3D,
 | 
				
			||||||
      VST4D
 | 
					      VST4D,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Vector shuffles:
 | 
				
			||||||
 | 
					      VREV64,       // reverse elements within 64-bit doublewords
 | 
				
			||||||
 | 
					      VREV32,       // reverse elements within 32-bit words
 | 
				
			||||||
 | 
					      VREV16        // reverse elements within 16-bit halfwords
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -135,11 +140,6 @@ namespace llvm {
 | 
				
			|||||||
    /// return the constant being splatted.  The ByteSize field indicates the
 | 
					    /// return the constant being splatted.  The ByteSize field indicates the
 | 
				
			||||||
    /// number of bytes of each element [1248].
 | 
					    /// number of bytes of each element [1248].
 | 
				
			||||||
    SDValue getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);
 | 
					    SDValue getVMOVImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// isVREVMask - Check if a vector shuffle corresponds to a VREV
 | 
					 | 
				
			||||||
    /// instruction with the specified blocksize.  (The order of the elements
 | 
					 | 
				
			||||||
    /// within each block of the vector is reversed.)
 | 
					 | 
				
			||||||
    bool isVREVMask(ShuffleVectorSDNode *N, unsigned blocksize);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //===--------------------------------------------------------------------===//
 | 
					  //===--------------------------------------------------------------------===//
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,6 +95,11 @@ def NEONvst3d     : SDNode<"ARMISD::VST3D", SDTARMVST3,
 | 
				
			|||||||
def NEONvst4d     : SDNode<"ARMISD::VST4D", SDTARMVST4,
 | 
					def NEONvst4d     : SDNode<"ARMISD::VST4D", SDTARMVST4,
 | 
				
			||||||
                           [SDNPHasChain, SDNPMayStore]>;
 | 
					                           [SDNPHasChain, SDNPMayStore]>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def SDTARMVSHUF   : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisSameAs<0, 1>]>;
 | 
				
			||||||
 | 
					def NEONvrev64    : SDNode<"ARMISD::VREV64", SDTARMVSHUF>;
 | 
				
			||||||
 | 
					def NEONvrev32    : SDNode<"ARMISD::VREV32", SDTARMVSHUF>;
 | 
				
			||||||
 | 
					def NEONvrev16    : SDNode<"ARMISD::VREV16", SDTARMVSHUF>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//===----------------------------------------------------------------------===//
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
// NEON operand definitions
 | 
					// NEON operand definitions
 | 
				
			||||||
//===----------------------------------------------------------------------===//
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
@@ -1881,25 +1886,7 @@ def VCVTxs2fq : N2VCvtQ<0, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.s32",
 | 
				
			|||||||
def VCVTxu2fq : N2VCvtQ<1, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.u32",
 | 
					def VCVTxu2fq : N2VCvtQ<1, 1, 0b000000, 0b1110, 0, 1, "vcvt.f32.u32",
 | 
				
			||||||
                        v4f32, v4i32, int_arm_neon_vcvtfxu2fp>;
 | 
					                        v4f32, v4i32, int_arm_neon_vcvtfxu2fp>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//   VREV     : Vector Reverse
 | 
					// Vector Reverse.
 | 
				
			||||||
 | 
					 | 
				
			||||||
def vrev64_shuffle : PatFrag<(ops node:$in),
 | 
					 | 
				
			||||||
                             (vector_shuffle node:$in, undef), [{
 | 
					 | 
				
			||||||
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
 | 
					 | 
				
			||||||
  return ARM::isVREVMask(SVOp, 64);
 | 
					 | 
				
			||||||
}]>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def vrev32_shuffle : PatFrag<(ops node:$in),
 | 
					 | 
				
			||||||
                             (vector_shuffle node:$in, undef), [{
 | 
					 | 
				
			||||||
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
 | 
					 | 
				
			||||||
  return ARM::isVREVMask(SVOp, 32);
 | 
					 | 
				
			||||||
}]>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def vrev16_shuffle : PatFrag<(ops node:$in),
 | 
					 | 
				
			||||||
                             (vector_shuffle node:$in, undef), [{
 | 
					 | 
				
			||||||
  ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(N);
 | 
					 | 
				
			||||||
  return ARM::isVREVMask(SVOp, 16);
 | 
					 | 
				
			||||||
}]>;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//   VREV64   : Vector Reverse elements within 64-bit doublewords
 | 
					//   VREV64   : Vector Reverse elements within 64-bit doublewords
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1907,12 +1894,12 @@ class VREV64D<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
				
			|||||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$dst),
 | 
					  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$dst),
 | 
				
			||||||
        (ins DPR:$src), NoItinerary, 
 | 
					        (ins DPR:$src), NoItinerary, 
 | 
				
			||||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
					        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
				
			||||||
        [(set DPR:$dst, (Ty (vrev64_shuffle (Ty DPR:$src))))]>;
 | 
					        [(set DPR:$dst, (Ty (NEONvrev64 (Ty DPR:$src))))]>;
 | 
				
			||||||
class VREV64Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
					class VREV64Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
				
			||||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$dst),
 | 
					  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$dst),
 | 
				
			||||||
        (ins QPR:$src), NoItinerary, 
 | 
					        (ins QPR:$src), NoItinerary, 
 | 
				
			||||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
					        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
				
			||||||
        [(set QPR:$dst, (Ty (vrev64_shuffle (Ty QPR:$src))))]>;
 | 
					        [(set QPR:$dst, (Ty (NEONvrev64 (Ty QPR:$src))))]>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def VREV64d8  : VREV64D<0b00, "vrev64.8", v8i8>;
 | 
					def VREV64d8  : VREV64D<0b00, "vrev64.8", v8i8>;
 | 
				
			||||||
def VREV64d16 : VREV64D<0b01, "vrev64.16", v4i16>;
 | 
					def VREV64d16 : VREV64D<0b01, "vrev64.16", v4i16>;
 | 
				
			||||||
@@ -1930,12 +1917,12 @@ class VREV32D<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
				
			|||||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$dst),
 | 
					  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$dst),
 | 
				
			||||||
        (ins DPR:$src), NoItinerary, 
 | 
					        (ins DPR:$src), NoItinerary, 
 | 
				
			||||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
					        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
				
			||||||
        [(set DPR:$dst, (Ty (vrev32_shuffle (Ty DPR:$src))))]>;
 | 
					        [(set DPR:$dst, (Ty (NEONvrev32 (Ty DPR:$src))))]>;
 | 
				
			||||||
class VREV32Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
					class VREV32Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
				
			||||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$dst),
 | 
					  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$dst),
 | 
				
			||||||
        (ins QPR:$src), NoItinerary, 
 | 
					        (ins QPR:$src), NoItinerary, 
 | 
				
			||||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
					        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
				
			||||||
        [(set QPR:$dst, (Ty (vrev32_shuffle (Ty QPR:$src))))]>;
 | 
					        [(set QPR:$dst, (Ty (NEONvrev32 (Ty QPR:$src))))]>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def VREV32d8  : VREV32D<0b00, "vrev32.8", v8i8>;
 | 
					def VREV32d8  : VREV32D<0b00, "vrev32.8", v8i8>;
 | 
				
			||||||
def VREV32d16 : VREV32D<0b01, "vrev32.16", v4i16>;
 | 
					def VREV32d16 : VREV32D<0b01, "vrev32.16", v4i16>;
 | 
				
			||||||
@@ -1949,12 +1936,12 @@ class VREV16D<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
				
			|||||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$dst),
 | 
					  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$dst),
 | 
				
			||||||
        (ins DPR:$src), NoItinerary, 
 | 
					        (ins DPR:$src), NoItinerary, 
 | 
				
			||||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
					        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
				
			||||||
        [(set DPR:$dst, (Ty (vrev16_shuffle (Ty DPR:$src))))]>;
 | 
					        [(set DPR:$dst, (Ty (NEONvrev16 (Ty DPR:$src))))]>;
 | 
				
			||||||
class VREV16Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
					class VREV16Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
				
			||||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$dst),
 | 
					  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$dst),
 | 
				
			||||||
        (ins QPR:$src), NoItinerary, 
 | 
					        (ins QPR:$src), NoItinerary, 
 | 
				
			||||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
					        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
				
			||||||
        [(set QPR:$dst, (Ty (vrev16_shuffle (Ty QPR:$src))))]>;
 | 
					        [(set QPR:$dst, (Ty (NEONvrev16 (Ty QPR:$src))))]>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def VREV16d8  : VREV16D<0b00, "vrev16.8", v8i8>;
 | 
					def VREV16d8  : VREV16D<0b00, "vrev16.8", v8i8>;
 | 
				
			||||||
def VREV16q8  : VREV16Q<0b00, "vrev16.8", v16i8>;
 | 
					def VREV16q8  : VREV16Q<0b00, "vrev16.8", v16i8>;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user