10b57cec5SDimitry Andric //===-- SparcISelLowering.h - Sparc DAG Lowering Interface ------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the interfaces that Sparc uses to lower LLVM code into a 100b57cec5SDimitry Andric // selection DAG. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "Sparc.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace llvm { 210b57cec5SDimitry Andric class SparcSubtarget; 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace SPISD { 240b57cec5SDimitry Andric enum NodeType : unsigned { 250b57cec5SDimitry Andric FIRST_NUMBER = ISD::BUILTIN_OP_END, 260b57cec5SDimitry Andric CMPICC, // Compare two GPR operands, set icc+xcc. 270b57cec5SDimitry Andric CMPFCC, // Compare two FP operands, set fcc. 28bdd1243dSDimitry Andric CMPFCC_V9, // Compare two FP operands, set fcc (v9 variant). 290b57cec5SDimitry Andric BRICC, // Branch to dest on icc condition 30bdd1243dSDimitry Andric BPICC, // Branch to dest on icc condition, with prediction (64-bit only). 31bdd1243dSDimitry Andric BPXCC, // Branch to dest on xcc condition, with prediction (64-bit only). 320b57cec5SDimitry Andric BRFCC, // Branch to dest on fcc condition 33bdd1243dSDimitry Andric BRFCC_V9, // Branch to dest on fcc condition (v9 variant). 3406c3fb27SDimitry Andric BR_REG, // Branch to dest using the comparison of a register with zero. 350b57cec5SDimitry Andric SELECT_ICC, // Select between two values using the current ICC flags. 360b57cec5SDimitry Andric SELECT_XCC, // Select between two values using the current XCC flags. 370b57cec5SDimitry Andric SELECT_FCC, // Select between two values using the current FCC flags. 38bdd1243dSDimitry Andric SELECT_REG, // Select between two values using the comparison of a register 39bdd1243dSDimitry Andric // with zero. 400b57cec5SDimitry Andric 41bdd1243dSDimitry Andric Hi, 42bdd1243dSDimitry Andric Lo, // Hi/Lo operations, typically on a global address. 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric FTOI, // FP to Int within a FP register. 450b57cec5SDimitry Andric ITOF, // Int to FP within a FP register. 460b57cec5SDimitry Andric FTOX, // FP to Int64 within a FP register. 470b57cec5SDimitry Andric XTOF, // Int64 to FP within a FP register. 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric CALL, // A call instruction. 5006c3fb27SDimitry Andric RET_GLUE, // Return with a glue operand. 510b57cec5SDimitry Andric GLOBAL_BASE_REG, // Global base reg for PIC. 520b57cec5SDimitry Andric FLUSHW, // FLUSH register windows to stack. 530b57cec5SDimitry Andric 5481ad6265SDimitry Andric TAIL_CALL, // Tail call 5581ad6265SDimitry Andric 560b57cec5SDimitry Andric TLS_ADD, // For Thread Local Storage (TLS). 570b57cec5SDimitry Andric TLS_LD, 5881ad6265SDimitry Andric TLS_CALL, 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric LOAD_GDOP, // Load operation w/ gdop relocation. 610b57cec5SDimitry Andric }; 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric class SparcTargetLowering : public TargetLowering { 650b57cec5SDimitry Andric const SparcSubtarget *Subtarget; 660b57cec5SDimitry Andric public: 670b57cec5SDimitry Andric SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI); 680b57cec5SDimitry Andric SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric bool useSoftFloat() const override; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// computeKnownBitsForTargetNode - Determine which of the bits specified 730b57cec5SDimitry Andric /// in Mask are known to be either zero or one and return them in the 740b57cec5SDimitry Andric /// KnownZero/KnownOne bitsets. 750b57cec5SDimitry Andric void computeKnownBitsForTargetNode(const SDValue Op, 760b57cec5SDimitry Andric KnownBits &Known, 770b57cec5SDimitry Andric const APInt &DemandedElts, 780b57cec5SDimitry Andric const SelectionDAG &DAG, 790b57cec5SDimitry Andric unsigned Depth = 0) const override; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric MachineBasicBlock * 820b57cec5SDimitry Andric EmitInstrWithCustomInserter(MachineInstr &MI, 830b57cec5SDimitry Andric MachineBasicBlock *MBB) const override; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric const char *getTargetNodeName(unsigned Opcode) const override; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric ConstraintType getConstraintType(StringRef Constraint) const override; 880b57cec5SDimitry Andric ConstraintWeight 890b57cec5SDimitry Andric getSingleConstraintMatchWeight(AsmOperandInfo &info, 900b57cec5SDimitry Andric const char *constraint) const override; 91*5f757f3fSDimitry Andric void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, 920b57cec5SDimitry Andric std::vector<SDValue> &Ops, 930b57cec5SDimitry Andric SelectionDAG &DAG) const override; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> 960b57cec5SDimitry Andric getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 970b57cec5SDimitry Andric StringRef Constraint, MVT VT) const override; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 1000b57cec5SDimitry Andric MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 1010b57cec5SDimitry Andric return MVT::i32; 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 104480093f4SDimitry Andric Register getRegisterByName(const char* RegName, LLT VT, 1058bcb0991SDimitry Andric const MachineFunction &MF) const override; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// If a physical register, this returns the register that receives the 1080b57cec5SDimitry Andric /// exception address on entry to an EH pad. 1095ffd83dbSDimitry Andric Register 1100b57cec5SDimitry Andric getExceptionPointerRegister(const Constant *PersonalityFn) const override { 1110b57cec5SDimitry Andric return SP::I0; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric /// If a physical register, this returns the register that receives the 1150b57cec5SDimitry Andric /// exception typeid on entry to a landing pad. 1165ffd83dbSDimitry Andric Register 1170b57cec5SDimitry Andric getExceptionSelectorRegister(const Constant *PersonalityFn) const override { 1180b57cec5SDimitry Andric return SP::I1; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// Override to support customized stack guard loading. 1220b57cec5SDimitry Andric bool useLoadStackGuardNode() const override; 1230b57cec5SDimitry Andric void insertSSPDeclarations(Module &M) const override; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// getSetCCResultType - Return the ISD::SETCC ValueType 1260b57cec5SDimitry Andric EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 1270b57cec5SDimitry Andric EVT VT) const override; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric SDValue 1300b57cec5SDimitry Andric LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1310b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1320b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1330b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1340b57cec5SDimitry Andric SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv, 1350b57cec5SDimitry Andric bool isVarArg, 1360b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1370b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1380b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1390b57cec5SDimitry Andric SDValue LowerFormalArguments_64(SDValue Chain, CallingConv::ID CallConv, 1400b57cec5SDimitry Andric bool isVarArg, 1410b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 1420b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 1430b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric SDValue 1460b57cec5SDimitry Andric LowerCall(TargetLowering::CallLoweringInfo &CLI, 1470b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 1480b57cec5SDimitry Andric SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI, 1490b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1500b57cec5SDimitry Andric SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, 1510b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 1520b57cec5SDimitry Andric 153f3fd488fSDimitry Andric bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 154f3fd488fSDimitry Andric bool isVarArg, 155f3fd488fSDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 156f3fd488fSDimitry Andric LLVMContext &Context) const override; 157f3fd488fSDimitry Andric 1580b57cec5SDimitry Andric SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1590b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1600b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 1610b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG) const override; 1620b57cec5SDimitry Andric SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv, 1630b57cec5SDimitry Andric bool IsVarArg, 1640b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1650b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 1660b57cec5SDimitry Andric const SDLoc &DL, SelectionDAG &DAG) const; 1670b57cec5SDimitry Andric SDValue LowerReturn_64(SDValue Chain, CallingConv::ID CallConv, 1680b57cec5SDimitry Andric bool IsVarArg, 1690b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 1700b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 1710b57cec5SDimitry Andric const SDLoc &DL, SelectionDAG &DAG) const; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 1740b57cec5SDimitry Andric SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 1750b57cec5SDimitry Andric SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 1760b57cec5SDimitry Andric SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 1790b57cec5SDimitry Andric SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 1800b57cec5SDimitry Andric SelectionDAG &DAG) const; 1810b57cec5SDimitry Andric SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric SDValue LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, 1840b57cec5SDimitry Andric const SDLoc &DL, SelectionDAG &DAG) const; 1850b57cec5SDimitry Andric SDValue LowerF128Op(SDValue Op, SelectionDAG &DAG, 1860b57cec5SDimitry Andric const char *LibFuncName, 1870b57cec5SDimitry Andric unsigned numArgs) const; 1880b57cec5SDimitry Andric SDValue LowerF128Compare(SDValue LHS, SDValue RHS, unsigned &SPCC, 1890b57cec5SDimitry Andric const SDLoc &DL, SelectionDAG &DAG) const; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric SDValue PerformBITCASTCombine(SDNode *N, DAGCombinerInfo &DCI) const; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric SDValue bitcastConstantFPToInt(ConstantFPSDNode *C, const SDLoc &DL, 1960b57cec5SDimitry Andric SelectionDAG &DAG) const; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 1990b57cec5SDimitry Andric 20081ad6265SDimitry Andric bool IsEligibleForTailCallOptimization(CCState &CCInfo, 20181ad6265SDimitry Andric CallLoweringInfo &CLI, 20281ad6265SDimitry Andric MachineFunction &MF) const; 20381ad6265SDimitry Andric 2040b57cec5SDimitry Andric bool ShouldShrinkFPConstant(EVT VT) const override { 2050b57cec5SDimitry Andric // Do not shrink FP constpool if VT == MVT::f128. 2060b57cec5SDimitry Andric // (ldd, call _Q_fdtoq) is more expensive than two ldds. 2070b57cec5SDimitry Andric return VT != MVT::f128; 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric bool shouldInsertFencesForAtomic(const Instruction *I) const override { 2110b57cec5SDimitry Andric // FIXME: We insert fences for each atomics and generate 2120b57cec5SDimitry Andric // sub-optimal code for PSO/TSO. (Approximately nobody uses any 2130b57cec5SDimitry Andric // mode but TSO, which makes this even more silly) 2140b57cec5SDimitry Andric return true; 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric void ReplaceNodeResults(SDNode *N, 2200b57cec5SDimitry Andric SmallVectorImpl<SDValue>& Results, 2210b57cec5SDimitry Andric SelectionDAG &DAG) const override; 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric MachineBasicBlock *expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB, 2240b57cec5SDimitry Andric unsigned BROpcode) const; 225*5f757f3fSDimitry Andric 226*5f757f3fSDimitry Andric void AdjustInstrPostInstrSelection(MachineInstr &MI, 227*5f757f3fSDimitry Andric SDNode *Node) const override; 2280b57cec5SDimitry Andric }; 2290b57cec5SDimitry Andric } // end namespace llvm 2300b57cec5SDimitry Andric 231*5f757f3fSDimitry Andric #endif // LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 232