mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 21:31:03 +00:00
Add basic support for NEON modified immediates besides VMOV.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106030 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2ebb4f81f7
commit
827b2106fe
@ -2766,10 +2766,18 @@ static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
|
||||
/// bits7-0=Immediate.
|
||||
static SDValue isNEONModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
|
||||
unsigned SplatBitSize, SelectionDAG &DAG,
|
||||
bool DoEncode) {
|
||||
bool isVMOV, bool DoEncode) {
|
||||
unsigned Op, Cmode, Imm;
|
||||
EVT VT;
|
||||
|
||||
// SplatBitSize is set to the smallest size that splats the vector, so a
|
||||
// zero vector will always have SplatBitSize == 8. However, NEON modified
|
||||
// immediate instructions others than VMOV do not support the 8-bit encoding
|
||||
// of a zero vector, and the default encoding of zero is supposed to be the
|
||||
// 32-bit version.
|
||||
if (SplatBits == 0)
|
||||
SplatBitSize = 32;
|
||||
|
||||
Op = 0;
|
||||
switch (SplatBitSize) {
|
||||
case 8:
|
||||
@ -2855,6 +2863,8 @@ static SDValue isNEONModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
|
||||
|
||||
case 64: {
|
||||
// NEON has a 64-bit VMOV splat where each byte is either 0 or 0xff.
|
||||
if (!isVMOV)
|
||||
return SDValue();
|
||||
uint64_t BitMask = 0xff;
|
||||
uint64_t Val = 0;
|
||||
unsigned ImmMask = 1;
|
||||
@ -2892,7 +2902,8 @@ static SDValue isNEONModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
|
||||
/// with a "modified immediate" operand (e.g., VMOV) of the specified element
|
||||
/// size, return the encoded value for that immediate. The ByteSize field
|
||||
/// indicates the number of bytes of each element [1248].
|
||||
SDValue ARM::getNEONModImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
|
||||
SDValue ARM::getNEONModImm(SDNode *N, unsigned ByteSize, bool isVMOV,
|
||||
SelectionDAG &DAG) {
|
||||
BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N);
|
||||
APInt SplatBits, SplatUndef;
|
||||
unsigned SplatBitSize;
|
||||
@ -2905,7 +2916,7 @@ SDValue ARM::getNEONModImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
|
||||
return SDValue();
|
||||
|
||||
return isNEONModifiedImm(SplatBits.getZExtValue(), SplatUndef.getZExtValue(),
|
||||
SplatBitSize, DAG, true);
|
||||
SplatBitSize, DAG, isVMOV, true);
|
||||
}
|
||||
|
||||
static bool isVEXTMask(const SmallVectorImpl<int> &M, EVT VT,
|
||||
@ -3148,7 +3159,7 @@ static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
|
||||
// Check if an immediate VMOV works.
|
||||
SDValue Val = isNEONModifiedImm(SplatBits.getZExtValue(),
|
||||
SplatUndef.getZExtValue(),
|
||||
SplatBitSize, DAG, false);
|
||||
SplatBitSize, DAG, true, false);
|
||||
if (Val.getNode())
|
||||
return BuildSplat(Val, VT, DAG, dl);
|
||||
}
|
||||
|
@ -154,7 +154,8 @@ namespace llvm {
|
||||
/// instruction with a "modified immediate" operand (e.g., VMOV) of the
|
||||
/// specified element size, return the encoded value for that immediate.
|
||||
/// The ByteSize field indicates the number of bytes of each element [1248].
|
||||
SDValue getNEONModImm(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);
|
||||
SDValue getNEONModImm(SDNode *N, unsigned ByteSize, bool isVMOV,
|
||||
SelectionDAG &DAG);
|
||||
|
||||
/// getVFPf32Imm / getVFPf64Imm - If the given fp immediate can be
|
||||
/// materialized with a VMOV.f32 / VMOV.f64 (i.e. fconsts / fconstd)
|
||||
|
@ -2820,34 +2820,34 @@ def VMOVQQQQ : PseudoInst<(outs QQQQPR:$dst), (ins QQQQPR:$src),
|
||||
|
||||
// VMOV_get_imm8 xform function: convert build_vector to VMOV.i8 imm.
|
||||
def VMOV_get_imm8 : SDNodeXForm<build_vector, [{
|
||||
return ARM::getNEONModImm(N, 1, *CurDAG);
|
||||
return ARM::getNEONModImm(N, 1, true, *CurDAG);
|
||||
}]>;
|
||||
def vmovImm8 : PatLeaf<(build_vector), [{
|
||||
return ARM::getNEONModImm(N, 1, *CurDAG).getNode() != 0;
|
||||
return ARM::getNEONModImm(N, 1, true, *CurDAG).getNode() != 0;
|
||||
}], VMOV_get_imm8>;
|
||||
|
||||
// VMOV_get_imm16 xform function: convert build_vector to VMOV.i16 imm.
|
||||
def VMOV_get_imm16 : SDNodeXForm<build_vector, [{
|
||||
return ARM::getNEONModImm(N, 2, *CurDAG);
|
||||
return ARM::getNEONModImm(N, 2, true, *CurDAG);
|
||||
}]>;
|
||||
def vmovImm16 : PatLeaf<(build_vector), [{
|
||||
return ARM::getNEONModImm(N, 2, *CurDAG).getNode() != 0;
|
||||
return ARM::getNEONModImm(N, 2, true, *CurDAG).getNode() != 0;
|
||||
}], VMOV_get_imm16>;
|
||||
|
||||
// VMOV_get_imm32 xform function: convert build_vector to VMOV.i32 imm.
|
||||
def VMOV_get_imm32 : SDNodeXForm<build_vector, [{
|
||||
return ARM::getNEONModImm(N, 4, *CurDAG);
|
||||
return ARM::getNEONModImm(N, 4, true, *CurDAG);
|
||||
}]>;
|
||||
def vmovImm32 : PatLeaf<(build_vector), [{
|
||||
return ARM::getNEONModImm(N, 4, *CurDAG).getNode() != 0;
|
||||
return ARM::getNEONModImm(N, 4, true, *CurDAG).getNode() != 0;
|
||||
}], VMOV_get_imm32>;
|
||||
|
||||
// VMOV_get_imm64 xform function: convert build_vector to VMOV.i64 imm.
|
||||
def VMOV_get_imm64 : SDNodeXForm<build_vector, [{
|
||||
return ARM::getNEONModImm(N, 8, *CurDAG);
|
||||
return ARM::getNEONModImm(N, 8, true, *CurDAG);
|
||||
}]>;
|
||||
def vmovImm64 : PatLeaf<(build_vector), [{
|
||||
return ARM::getNEONModImm(N, 8, *CurDAG).getNode() != 0;
|
||||
return ARM::getNEONModImm(N, 8, true, *CurDAG).getNode() != 0;
|
||||
}], VMOV_get_imm64>;
|
||||
|
||||
// Note: Some of the cmode bits in the following VMOV instructions need to
|
||||
|
Loading…
x
Reference in New Issue
Block a user