Index: llvm/lib/Target/Xtensa/XtensaISelLowering.h =================================================================== --- llvm/lib/Target/Xtensa/XtensaISelLowering.h +++ llvm/lib/Target/Xtensa/XtensaISelLowering.h @@ -36,6 +36,8 @@ 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 @@ 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; }; Index: llvm/lib/Target/Xtensa/XtensaISelLowering.cpp =================================================================== --- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -46,6 +46,11 @@ 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); @@ -57,6 +62,11 @@ computeRegisterProperties(STI.getRegisterInfo()); } +bool XtensaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, + bool ForCodeSize) const { + return false; +} + //===----------------------------------------------------------------------===// // Calling conventions //===----------------------------------------------------------------------===// @@ -298,9 +308,45 @@ 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); + 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 = llvm::bit_cast(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); + 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"); }