mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-09 10:31:14 +00:00
Try using vmov.i32 to materialize FP32 constants that can't be materialized by
vmov.f32. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153696 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4b0b8ef1b0
commit
c0a9f820d8
@ -3672,27 +3672,6 @@ static SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
|
|
||||||
const ARMSubtarget *ST) const {
|
|
||||||
if (!ST->useNEONForSinglePrecisionFP() || !ST->hasVFP3() || ST->hasD16())
|
|
||||||
return SDValue();
|
|
||||||
|
|
||||||
ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
|
|
||||||
assert(Op.getValueType() == MVT::f32 &&
|
|
||||||
"ConstantFP custom lowering should only occur for f32.");
|
|
||||||
|
|
||||||
APFloat FPVal = CFP->getValueAPF();
|
|
||||||
int ImmVal = ARM_AM::getFP32Imm(FPVal);
|
|
||||||
if (ImmVal == -1)
|
|
||||||
return SDValue();
|
|
||||||
|
|
||||||
DebugLoc DL = Op.getDebugLoc();
|
|
||||||
SDValue NewVal = DAG.getTargetConstant(ImmVal, MVT::i32);
|
|
||||||
SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32, NewVal);
|
|
||||||
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
|
|
||||||
DAG.getConstant(0, MVT::i32));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// isNEONModifiedImm - Check if the specified splat value corresponds to a
|
/// isNEONModifiedImm - Check if the specified splat value corresponds to a
|
||||||
/// valid vector constant for a NEON instruction with a "modified immediate"
|
/// valid vector constant for a NEON instruction with a "modified immediate"
|
||||||
/// operand (e.g., VMOV). If so, return the encoded value.
|
/// operand (e.g., VMOV). If so, return the encoded value.
|
||||||
@ -3829,6 +3808,58 @@ static SDValue isNEONModifiedImm(uint64_t SplatBits, uint64_t SplatUndef,
|
|||||||
return DAG.getTargetConstant(EncodedVal, MVT::i32);
|
return DAG.getTargetConstant(EncodedVal, MVT::i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,
|
||||||
|
const ARMSubtarget *ST) const {
|
||||||
|
if (!ST->useNEONForSinglePrecisionFP() || !ST->hasVFP3() || ST->hasD16())
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);
|
||||||
|
assert(Op.getValueType() == MVT::f32 &&
|
||||||
|
"ConstantFP custom lowering should only occur for f32.");
|
||||||
|
|
||||||
|
// Try splatting with a VMOV.f32...
|
||||||
|
APFloat FPVal = CFP->getValueAPF();
|
||||||
|
int ImmVal = ARM_AM::getFP32Imm(FPVal);
|
||||||
|
if (ImmVal != -1) {
|
||||||
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
SDValue NewVal = DAG.getTargetConstant(ImmVal, MVT::i32);
|
||||||
|
SDValue VecConstant = DAG.getNode(ARMISD::VMOVFPIMM, DL, MVT::v2f32,
|
||||||
|
NewVal);
|
||||||
|
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecConstant,
|
||||||
|
DAG.getConstant(0, MVT::i32));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If that fails, try a VMOV.i32
|
||||||
|
EVT VMovVT;
|
||||||
|
unsigned iVal = FPVal.bitcastToAPInt().getZExtValue();
|
||||||
|
SDValue NewVal = isNEONModifiedImm(iVal, 0, 32, DAG, VMovVT, false,
|
||||||
|
VMOVModImm);
|
||||||
|
if (NewVal != SDValue()) {
|
||||||
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
SDValue VecConstant = DAG.getNode(ARMISD::VMOVIMM, DL, VMovVT,
|
||||||
|
NewVal);
|
||||||
|
SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
|
||||||
|
VecConstant);
|
||||||
|
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
|
||||||
|
DAG.getConstant(0, MVT::i32));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, try a VMVN.i32
|
||||||
|
NewVal = isNEONModifiedImm(~iVal & 0xffffffff, 0, 32, DAG, VMovVT, false,
|
||||||
|
VMVNModImm);
|
||||||
|
if (NewVal != SDValue()) {
|
||||||
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
SDValue VecConstant = DAG.getNode(ARMISD::VMVNIMM, DL, VMovVT, NewVal);
|
||||||
|
SDValue VecFConstant = DAG.getNode(ISD::BITCAST, DL, MVT::v2f32,
|
||||||
|
VecConstant);
|
||||||
|
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, VecFConstant,
|
||||||
|
DAG.getConstant(0, MVT::i32));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SDValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool isVEXTMask(ArrayRef<int> M, EVT VT,
|
static bool isVEXTMask(ArrayRef<int> M, EVT VT,
|
||||||
bool &ReverseVEXT, unsigned &Imm) {
|
bool &ReverseVEXT, unsigned &Imm) {
|
||||||
unsigned NumElts = VT.getVectorNumElements();
|
unsigned NumElts = VT.getVectorNumElements();
|
||||||
|
Loading…
Reference in New Issue
Block a user