diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index 3f43379364792..9ed24c994fd81 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -44,7 +44,12 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm, setBooleanVectorContents(ZeroOrOneBooleanContent); setMinFunctionAlignment(Align(4)); - + + setOperationAction(ISD::Constant, MVT::i32, Custom); + setOperationAction(ISD::Constant, MVT::i64, Expand); + setOperationAction(ISD::ConstantFP, MVT::f32, Custom); + setOperationAction(ISD::ConstantFP, MVT::f64, Expand); + // No sign extend instructions for i1 for (MVT VT : MVT::integer_valuetypes()) { setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); @@ -56,6 +61,11 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm, computeRegisterProperties(STI.getRegisterInfo()); } +bool XtensaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, + bool ForCodeSize) const { + return false; +} + //===----------------------------------------------------------------------===// // Calling conventions //===----------------------------------------------------------------------===// @@ -297,9 +307,45 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, return DAG.getNode(XtensaISD::RET_FLAG, DL, MVT::Other, RetOps); } +SDValue XtensaTargetLowering::LowerImmediate(SDValue Op, + SelectionDAG &DAG) const { + const ConstantSDNode *CN = cast(Op); + SDLoc DL(CN); + APInt apval = CN->getAPIntValue(); + int64_t value = apval.getSExtValue(); + if (Op.getValueType() == MVT::i32) { + if (value > -2048 && value <= 2047) + return Op; + Type *Ty = Type::getInt32Ty(*DAG.getContext()); + Constant *CV = ConstantInt::get(Ty, value); + SDValue CP = DAG.getConstantPool(CV, MVT::i32, 0, 0, false); + return CP; + } + return Op; +} + +SDValue XtensaTargetLowering::LowerImmediateFP(SDValue Op, + SelectionDAG &DAG) const { + const ConstantFPSDNode *CN = cast(Op); + SDLoc DL(CN); + APFloat apval = CN->getValueAPF(); + int64_t value = FloatToBits(CN->getValueAPF().convertToFloat()); + if (Op.getValueType() == MVT::f32) { + Type *Ty = Type::getInt32Ty(*DAG.getContext()); + Constant *CV = ConstantInt::get(Ty, value); + SDValue CP = DAG.getConstantPool(CV, MVT::i32, 0, 0, false); + return DAG.getNode(ISD::BITCAST, DL, MVT::f32, CP); + } + return Op; +} + SDValue XtensaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { + case ISD::Constant: + return LowerImmediate(Op, DAG); + case ISD::ConstantFP: + return LowerImmediateFP(Op, DAG); default: llvm_unreachable("Unexpected node to lower"); } diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h index 2df2a074fe25f..e2ed301e45ebe 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -36,6 +36,8 @@ class XtensaTargetLowering : public TargetLowering { explicit XtensaTargetLowering(const TargetMachine &TM, const XtensaSubtarget &STI); + bool isFPImmLegal(const APFloat &Imm, EVT VT, + bool ForCodeSize) const override; const char *getTargetNodeName(unsigned Opcode) const override; SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, @@ -57,6 +59,9 @@ class XtensaTargetLowering : public TargetLowering { private: const XtensaSubtarget &Subtarget; + SDValue LowerImmediate(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerImmediateFP(SDValue Op, SelectionDAG &DAG) const; + CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; };