17330f729Sjoerg //===-- SparcISelLowering.h - Sparc DAG Lowering Interface ------*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // This file defines the interfaces that Sparc uses to lower LLVM code into a 107330f729Sjoerg // selection DAG. 117330f729Sjoerg // 127330f729Sjoerg //===----------------------------------------------------------------------===// 137330f729Sjoerg 147330f729Sjoerg #ifndef LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 157330f729Sjoerg #define LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 167330f729Sjoerg 177330f729Sjoerg #include "Sparc.h" 187330f729Sjoerg #include "llvm/CodeGen/TargetLowering.h" 197330f729Sjoerg 207330f729Sjoerg namespace llvm { 217330f729Sjoerg class SparcSubtarget; 227330f729Sjoerg 237330f729Sjoerg namespace SPISD { 247330f729Sjoerg enum NodeType : unsigned { 257330f729Sjoerg FIRST_NUMBER = ISD::BUILTIN_OP_END, 267330f729Sjoerg CMPICC, // Compare two GPR operands, set icc+xcc. 277330f729Sjoerg CMPFCC, // Compare two FP operands, set fcc. 287330f729Sjoerg BRICC, // Branch to dest on icc condition 297330f729Sjoerg BRXCC, // Branch to dest on xcc condition (64-bit only). 307330f729Sjoerg BRFCC, // Branch to dest on fcc condition 317330f729Sjoerg SELECT_ICC, // Select between two values using the current ICC flags. 327330f729Sjoerg SELECT_XCC, // Select between two values using the current XCC flags. 337330f729Sjoerg SELECT_FCC, // Select between two values using the current FCC flags. 347330f729Sjoerg 357330f729Sjoerg Hi, Lo, // Hi/Lo operations, typically on a global address. 367330f729Sjoerg 377330f729Sjoerg FTOI, // FP to Int within a FP register. 387330f729Sjoerg ITOF, // Int to FP within a FP register. 397330f729Sjoerg FTOX, // FP to Int64 within a FP register. 407330f729Sjoerg XTOF, // Int64 to FP within a FP register. 417330f729Sjoerg 427330f729Sjoerg CALL, // A call instruction. 437330f729Sjoerg RET_FLAG, // Return with a flag operand. 447330f729Sjoerg GLOBAL_BASE_REG, // Global base reg for PIC. 457330f729Sjoerg FLUSHW, // FLUSH register windows to stack. 467330f729Sjoerg 477330f729Sjoerg TLS_ADD, // For Thread Local Storage (TLS). 487330f729Sjoerg TLS_LD, 497330f729Sjoerg TLS_CALL 507330f729Sjoerg }; 517330f729Sjoerg } 527330f729Sjoerg 537330f729Sjoerg class SparcTargetLowering : public TargetLowering { 547330f729Sjoerg const SparcSubtarget *Subtarget; 557330f729Sjoerg public: 567330f729Sjoerg SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI); 577330f729Sjoerg SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 587330f729Sjoerg 597330f729Sjoerg bool useSoftFloat() const override; 607330f729Sjoerg 617330f729Sjoerg /// computeKnownBitsForTargetNode - Determine which of the bits specified 627330f729Sjoerg /// in Mask are known to be either zero or one and return them in the 637330f729Sjoerg /// KnownZero/KnownOne bitsets. 647330f729Sjoerg void computeKnownBitsForTargetNode(const SDValue Op, 657330f729Sjoerg KnownBits &Known, 667330f729Sjoerg const APInt &DemandedElts, 677330f729Sjoerg const SelectionDAG &DAG, 687330f729Sjoerg unsigned Depth = 0) const override; 697330f729Sjoerg 707330f729Sjoerg MachineBasicBlock * 717330f729Sjoerg EmitInstrWithCustomInserter(MachineInstr &MI, 727330f729Sjoerg MachineBasicBlock *MBB) const override; 737330f729Sjoerg 747330f729Sjoerg const char *getTargetNodeName(unsigned Opcode) const override; 757330f729Sjoerg 767330f729Sjoerg ConstraintType getConstraintType(StringRef Constraint) const override; 777330f729Sjoerg ConstraintWeight 787330f729Sjoerg getSingleConstraintMatchWeight(AsmOperandInfo &info, 797330f729Sjoerg const char *constraint) const override; 807330f729Sjoerg void LowerAsmOperandForConstraint(SDValue Op, 817330f729Sjoerg std::string &Constraint, 827330f729Sjoerg std::vector<SDValue> &Ops, 837330f729Sjoerg SelectionDAG &DAG) const override; 847330f729Sjoerg 857330f729Sjoerg std::pair<unsigned, const TargetRegisterClass *> 867330f729Sjoerg getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 877330f729Sjoerg StringRef Constraint, MVT VT) const override; 887330f729Sjoerg 897330f729Sjoerg bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; getScalarShiftAmountTy(const DataLayout &,EVT)907330f729Sjoerg MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 917330f729Sjoerg return MVT::i32; 927330f729Sjoerg } 937330f729Sjoerg 94*82d56013Sjoerg Register getRegisterByName(const char* RegName, LLT VT, 957330f729Sjoerg const MachineFunction &MF) const override; 967330f729Sjoerg 977330f729Sjoerg /// If a physical register, this returns the register that receives the 987330f729Sjoerg /// exception address on entry to an EH pad. 99*82d56013Sjoerg Register getExceptionPointerRegister(const Constant * PersonalityFn)1007330f729Sjoerg getExceptionPointerRegister(const Constant *PersonalityFn) const override { 1017330f729Sjoerg return SP::I0; 1027330f729Sjoerg } 1037330f729Sjoerg 1047330f729Sjoerg /// If a physical register, this returns the register that receives the 1057330f729Sjoerg /// exception typeid on entry to a landing pad. 106*82d56013Sjoerg Register getExceptionSelectorRegister(const Constant * PersonalityFn)1077330f729Sjoerg getExceptionSelectorRegister(const Constant *PersonalityFn) const override { 1087330f729Sjoerg return SP::I1; 1097330f729Sjoerg } 1107330f729Sjoerg 1117330f729Sjoerg /// Override to support customized stack guard loading. 1127330f729Sjoerg bool useLoadStackGuardNode() const override; 1137330f729Sjoerg void insertSSPDeclarations(Module &M) const override; 1147330f729Sjoerg 1157330f729Sjoerg /// getSetCCResultType - Return the ISD::SETCC ValueType 1167330f729Sjoerg EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 1177330f729Sjoerg EVT VT) const override; 1187330f729Sjoerg 1197330f729Sjoerg SDValue 1207330f729Sjoerg LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1217330f729Sjoerg const SmallVectorImpl<ISD::InputArg> &Ins, 1227330f729Sjoerg const SDLoc &dl, SelectionDAG &DAG, 1237330f729Sjoerg SmallVectorImpl<SDValue> &InVals) const override; 1247330f729Sjoerg SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv, 1257330f729Sjoerg bool isVarArg, 1267330f729Sjoerg const SmallVectorImpl<ISD::InputArg> &Ins, 1277330f729Sjoerg const SDLoc &dl, SelectionDAG &DAG, 1287330f729Sjoerg SmallVectorImpl<SDValue> &InVals) const; 1297330f729Sjoerg SDValue LowerFormalArguments_64(SDValue Chain, CallingConv::ID CallConv, 1307330f729Sjoerg bool isVarArg, 1317330f729Sjoerg const SmallVectorImpl<ISD::InputArg> &Ins, 1327330f729Sjoerg const SDLoc &dl, SelectionDAG &DAG, 1337330f729Sjoerg SmallVectorImpl<SDValue> &InVals) const; 1347330f729Sjoerg 1357330f729Sjoerg SDValue 1367330f729Sjoerg LowerCall(TargetLowering::CallLoweringInfo &CLI, 1377330f729Sjoerg SmallVectorImpl<SDValue> &InVals) const override; 1387330f729Sjoerg SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI, 1397330f729Sjoerg SmallVectorImpl<SDValue> &InVals) const; 1407330f729Sjoerg SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, 1417330f729Sjoerg SmallVectorImpl<SDValue> &InVals) const; 1427330f729Sjoerg 1437330f729Sjoerg SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1447330f729Sjoerg const SmallVectorImpl<ISD::OutputArg> &Outs, 1457330f729Sjoerg const SmallVectorImpl<SDValue> &OutVals, 1467330f729Sjoerg const SDLoc &dl, SelectionDAG &DAG) const override; 1477330f729Sjoerg SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv, 1487330f729Sjoerg bool IsVarArg, 1497330f729Sjoerg const SmallVectorImpl<ISD::OutputArg> &Outs, 1507330f729Sjoerg const SmallVectorImpl<SDValue> &OutVals, 1517330f729Sjoerg const SDLoc &DL, SelectionDAG &DAG) const; 1527330f729Sjoerg SDValue LowerReturn_64(SDValue Chain, CallingConv::ID CallConv, 1537330f729Sjoerg bool IsVarArg, 1547330f729Sjoerg const SmallVectorImpl<ISD::OutputArg> &Outs, 1557330f729Sjoerg const SmallVectorImpl<SDValue> &OutVals, 1567330f729Sjoerg const SDLoc &DL, SelectionDAG &DAG) const; 1577330f729Sjoerg 1587330f729Sjoerg SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 1597330f729Sjoerg SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 1607330f729Sjoerg SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 1617330f729Sjoerg SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 1627330f729Sjoerg 1637330f729Sjoerg SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 1647330f729Sjoerg SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 1657330f729Sjoerg SelectionDAG &DAG) const; 1667330f729Sjoerg SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 1677330f729Sjoerg 1687330f729Sjoerg SDValue LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, 1697330f729Sjoerg const SDLoc &DL, SelectionDAG &DAG) const; 1707330f729Sjoerg SDValue LowerF128Op(SDValue Op, SelectionDAG &DAG, 1717330f729Sjoerg const char *LibFuncName, 1727330f729Sjoerg unsigned numArgs) const; 1737330f729Sjoerg SDValue LowerF128Compare(SDValue LHS, SDValue RHS, unsigned &SPCC, 1747330f729Sjoerg const SDLoc &DL, SelectionDAG &DAG) const; 1757330f729Sjoerg 1767330f729Sjoerg SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 1777330f729Sjoerg 1787330f729Sjoerg SDValue PerformBITCASTCombine(SDNode *N, DAGCombinerInfo &DCI) const; 1797330f729Sjoerg 1807330f729Sjoerg SDValue bitcastConstantFPToInt(ConstantFPSDNode *C, const SDLoc &DL, 1817330f729Sjoerg SelectionDAG &DAG) const; 1827330f729Sjoerg 1837330f729Sjoerg SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 1847330f729Sjoerg ShouldShrinkFPConstant(EVT VT)1857330f729Sjoerg bool ShouldShrinkFPConstant(EVT VT) const override { 1867330f729Sjoerg // Do not shrink FP constpool if VT == MVT::f128. 1877330f729Sjoerg // (ldd, call _Q_fdtoq) is more expensive than two ldds. 1887330f729Sjoerg return VT != MVT::f128; 1897330f729Sjoerg } 1907330f729Sjoerg shouldInsertFencesForAtomic(const Instruction * I)1917330f729Sjoerg bool shouldInsertFencesForAtomic(const Instruction *I) const override { 1927330f729Sjoerg // FIXME: We insert fences for each atomics and generate 1937330f729Sjoerg // sub-optimal code for PSO/TSO. (Approximately nobody uses any 1947330f729Sjoerg // mode but TSO, which makes this even more silly) 1957330f729Sjoerg return true; 1967330f729Sjoerg } 1977330f729Sjoerg 1987330f729Sjoerg AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 1997330f729Sjoerg 2007330f729Sjoerg void ReplaceNodeResults(SDNode *N, 2017330f729Sjoerg SmallVectorImpl<SDValue>& Results, 2027330f729Sjoerg SelectionDAG &DAG) const override; 2037330f729Sjoerg 2047330f729Sjoerg MachineBasicBlock *expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB, 2057330f729Sjoerg unsigned BROpcode) const; 2067330f729Sjoerg }; 2077330f729Sjoerg } // end namespace llvm 2087330f729Sjoerg 2097330f729Sjoerg #endif // SPARC_ISELLOWERING_H 210