1*9880d681SAndroid Build Coastguard Worker //===-- SparcISelLowering.h - Sparc DAG Lowering Interface ------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file defines the interfaces that Sparc uses to lower LLVM code into a 11*9880d681SAndroid Build Coastguard Worker // selection DAG. 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "Sparc.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker namespace llvm { 22*9880d681SAndroid Build Coastguard Worker class SparcSubtarget; 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker namespace SPISD { 25*9880d681SAndroid Build Coastguard Worker enum NodeType : unsigned { 26*9880d681SAndroid Build Coastguard Worker FIRST_NUMBER = ISD::BUILTIN_OP_END, 27*9880d681SAndroid Build Coastguard Worker CMPICC, // Compare two GPR operands, set icc+xcc. 28*9880d681SAndroid Build Coastguard Worker CMPFCC, // Compare two FP operands, set fcc. 29*9880d681SAndroid Build Coastguard Worker BRICC, // Branch to dest on icc condition 30*9880d681SAndroid Build Coastguard Worker BRXCC, // Branch to dest on xcc condition (64-bit only). 31*9880d681SAndroid Build Coastguard Worker BRFCC, // Branch to dest on fcc condition 32*9880d681SAndroid Build Coastguard Worker SELECT_ICC, // Select between two values using the current ICC flags. 33*9880d681SAndroid Build Coastguard Worker SELECT_XCC, // Select between two values using the current XCC flags. 34*9880d681SAndroid Build Coastguard Worker SELECT_FCC, // Select between two values using the current FCC flags. 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker EH_SJLJ_SETJMP, // builtin setjmp operation 37*9880d681SAndroid Build Coastguard Worker EH_SJLJ_LONGJMP, // builtin longjmp operation 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker Hi, Lo, // Hi/Lo operations, typically on a global address. 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker FTOI, // FP to Int within a FP register. 42*9880d681SAndroid Build Coastguard Worker ITOF, // Int to FP within a FP register. 43*9880d681SAndroid Build Coastguard Worker FTOX, // FP to Int64 within a FP register. 44*9880d681SAndroid Build Coastguard Worker XTOF, // Int64 to FP within a FP register. 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker CALL, // A call instruction. 47*9880d681SAndroid Build Coastguard Worker RET_FLAG, // Return with a flag operand. 48*9880d681SAndroid Build Coastguard Worker GLOBAL_BASE_REG, // Global base reg for PIC. 49*9880d681SAndroid Build Coastguard Worker FLUSHW, // FLUSH register windows to stack. 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker TLS_ADD, // For Thread Local Storage (TLS). 52*9880d681SAndroid Build Coastguard Worker TLS_LD, 53*9880d681SAndroid Build Coastguard Worker TLS_CALL 54*9880d681SAndroid Build Coastguard Worker }; 55*9880d681SAndroid Build Coastguard Worker } 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker class SparcTargetLowering : public TargetLowering { 58*9880d681SAndroid Build Coastguard Worker const SparcSubtarget *Subtarget; 59*9880d681SAndroid Build Coastguard Worker public: 60*9880d681SAndroid Build Coastguard Worker SparcTargetLowering(const TargetMachine &TM, const SparcSubtarget &STI); 61*9880d681SAndroid Build Coastguard Worker SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker bool useSoftFloat() const override; 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker /// computeKnownBitsForTargetNode - Determine which of the bits specified 66*9880d681SAndroid Build Coastguard Worker /// in Mask are known to be either zero or one and return them in the 67*9880d681SAndroid Build Coastguard Worker /// KnownZero/KnownOne bitsets. 68*9880d681SAndroid Build Coastguard Worker void computeKnownBitsForTargetNode(const SDValue Op, 69*9880d681SAndroid Build Coastguard Worker APInt &KnownZero, 70*9880d681SAndroid Build Coastguard Worker APInt &KnownOne, 71*9880d681SAndroid Build Coastguard Worker const SelectionDAG &DAG, 72*9880d681SAndroid Build Coastguard Worker unsigned Depth = 0) const override; 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker MachineBasicBlock * 75*9880d681SAndroid Build Coastguard Worker EmitInstrWithCustomInserter(MachineInstr &MI, 76*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB) const override; 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker const char *getTargetNodeName(unsigned Opcode) const override; 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker ConstraintType getConstraintType(StringRef Constraint) const override; 81*9880d681SAndroid Build Coastguard Worker ConstraintWeight 82*9880d681SAndroid Build Coastguard Worker getSingleConstraintMatchWeight(AsmOperandInfo &info, 83*9880d681SAndroid Build Coastguard Worker const char *constraint) const override; 84*9880d681SAndroid Build Coastguard Worker void LowerAsmOperandForConstraint(SDValue Op, 85*9880d681SAndroid Build Coastguard Worker std::string &Constraint, 86*9880d681SAndroid Build Coastguard Worker std::vector<SDValue> &Ops, 87*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const override; 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker unsigned getInlineAsmMemConstraint(StringRef ConstraintCode)90*9880d681SAndroid Build Coastguard Worker getInlineAsmMemConstraint(StringRef ConstraintCode) const override { 91*9880d681SAndroid Build Coastguard Worker if (ConstraintCode == "o") 92*9880d681SAndroid Build Coastguard Worker return InlineAsm::Constraint_o; 93*9880d681SAndroid Build Coastguard Worker return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); 94*9880d681SAndroid Build Coastguard Worker } 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, const TargetRegisterClass *> 97*9880d681SAndroid Build Coastguard Worker getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 98*9880d681SAndroid Build Coastguard Worker StringRef Constraint, MVT VT) const override; 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; getScalarShiftAmountTy(const DataLayout &,EVT)101*9880d681SAndroid Build Coastguard Worker MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 102*9880d681SAndroid Build Coastguard Worker return MVT::i32; 103*9880d681SAndroid Build Coastguard Worker } 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker unsigned getRegisterByName(const char* RegName, EVT VT, 106*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const override; 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Worker /// If a physical register, this returns the register that receives the 109*9880d681SAndroid Build Coastguard Worker /// exception address on entry to an EH pad. 110*9880d681SAndroid Build Coastguard Worker unsigned getExceptionPointerRegister(const Constant * PersonalityFn)111*9880d681SAndroid Build Coastguard Worker getExceptionPointerRegister(const Constant *PersonalityFn) const override { 112*9880d681SAndroid Build Coastguard Worker return SP::I0; 113*9880d681SAndroid Build Coastguard Worker } 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker /// If a physical register, this returns the register that receives the 116*9880d681SAndroid Build Coastguard Worker /// exception typeid on entry to a landing pad. 117*9880d681SAndroid Build Coastguard Worker unsigned getExceptionSelectorRegister(const Constant * PersonalityFn)118*9880d681SAndroid Build Coastguard Worker getExceptionSelectorRegister(const Constant *PersonalityFn) const override { 119*9880d681SAndroid Build Coastguard Worker return SP::I1; 120*9880d681SAndroid Build Coastguard Worker } 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker /// Override to support customized stack guard loading. 123*9880d681SAndroid Build Coastguard Worker bool useLoadStackGuardNode() const override; 124*9880d681SAndroid Build Coastguard Worker void insertSSPDeclarations(Module &M) const override; 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker /// getSetCCResultType - Return the ISD::SETCC ValueType 127*9880d681SAndroid Build Coastguard Worker EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 128*9880d681SAndroid Build Coastguard Worker EVT VT) const override; 129*9880d681SAndroid Build Coastguard Worker 130*9880d681SAndroid Build Coastguard Worker SDValue 131*9880d681SAndroid Build Coastguard Worker LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 132*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::InputArg> &Ins, 133*9880d681SAndroid Build Coastguard Worker const SDLoc &dl, SelectionDAG &DAG, 134*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const override; 135*9880d681SAndroid Build Coastguard Worker SDValue LowerFormalArguments_32(SDValue Chain, CallingConv::ID CallConv, 136*9880d681SAndroid Build Coastguard Worker bool isVarArg, 137*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::InputArg> &Ins, 138*9880d681SAndroid Build Coastguard Worker const SDLoc &dl, SelectionDAG &DAG, 139*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const; 140*9880d681SAndroid Build Coastguard Worker SDValue LowerFormalArguments_64(SDValue Chain, CallingConv::ID CallConv, 141*9880d681SAndroid Build Coastguard Worker bool isVarArg, 142*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::InputArg> &Ins, 143*9880d681SAndroid Build Coastguard Worker const SDLoc &dl, SelectionDAG &DAG, 144*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const; 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker SDValue 147*9880d681SAndroid Build Coastguard Worker LowerCall(TargetLowering::CallLoweringInfo &CLI, 148*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const override; 149*9880d681SAndroid Build Coastguard Worker SDValue LowerCall_32(TargetLowering::CallLoweringInfo &CLI, 150*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const; 151*9880d681SAndroid Build Coastguard Worker SDValue LowerCall_64(TargetLowering::CallLoweringInfo &CLI, 152*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const; 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 155*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::OutputArg> &Outs, 156*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<SDValue> &OutVals, 157*9880d681SAndroid Build Coastguard Worker const SDLoc &dl, SelectionDAG &DAG) const override; 158*9880d681SAndroid Build Coastguard Worker SDValue LowerReturn_32(SDValue Chain, CallingConv::ID CallConv, 159*9880d681SAndroid Build Coastguard Worker bool IsVarArg, 160*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::OutputArg> &Outs, 161*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<SDValue> &OutVals, 162*9880d681SAndroid Build Coastguard Worker const SDLoc &DL, SelectionDAG &DAG) const; 163*9880d681SAndroid Build Coastguard Worker SDValue LowerReturn_64(SDValue Chain, CallingConv::ID CallConv, 164*9880d681SAndroid Build Coastguard Worker bool IsVarArg, 165*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::OutputArg> &Outs, 166*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<SDValue> &OutVals, 167*9880d681SAndroid Build Coastguard Worker const SDLoc &DL, SelectionDAG &DAG) const; 168*9880d681SAndroid Build Coastguard Worker 169*9880d681SAndroid Build Coastguard Worker SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 170*9880d681SAndroid Build Coastguard Worker SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 171*9880d681SAndroid Build Coastguard Worker SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 172*9880d681SAndroid Build Coastguard Worker SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker SDValue LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG, 175*9880d681SAndroid Build Coastguard Worker const SparcTargetLowering &TLI) const ; 176*9880d681SAndroid Build Coastguard Worker SDValue LowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG, 177*9880d681SAndroid Build Coastguard Worker const SparcTargetLowering &TLI) const ; 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Worker unsigned getSRetArgSize(SelectionDAG &DAG, SDValue Callee) const; 180*9880d681SAndroid Build Coastguard Worker SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const; 181*9880d681SAndroid Build Coastguard Worker SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, 182*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const; 183*9880d681SAndroid Build Coastguard Worker SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const; 184*9880d681SAndroid Build Coastguard Worker 185*9880d681SAndroid Build Coastguard Worker SDValue LowerF128_LibCallArg(SDValue Chain, ArgListTy &Args, SDValue Arg, 186*9880d681SAndroid Build Coastguard Worker const SDLoc &DL, SelectionDAG &DAG) const; 187*9880d681SAndroid Build Coastguard Worker SDValue LowerF128Op(SDValue Op, SelectionDAG &DAG, 188*9880d681SAndroid Build Coastguard Worker const char *LibFuncName, 189*9880d681SAndroid Build Coastguard Worker unsigned numArgs) const; 190*9880d681SAndroid Build Coastguard Worker SDValue LowerF128Compare(SDValue LHS, SDValue RHS, unsigned &SPCC, 191*9880d681SAndroid Build Coastguard Worker const SDLoc &DL, SelectionDAG &DAG) const; 192*9880d681SAndroid Build Coastguard Worker 193*9880d681SAndroid Build Coastguard Worker SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 194*9880d681SAndroid Build Coastguard Worker ShouldShrinkFPConstant(EVT VT)195*9880d681SAndroid Build Coastguard Worker bool ShouldShrinkFPConstant(EVT VT) const override { 196*9880d681SAndroid Build Coastguard Worker // Do not shrink FP constpool if VT == MVT::f128. 197*9880d681SAndroid Build Coastguard Worker // (ldd, call _Q_fdtoq) is more expensive than two ldds. 198*9880d681SAndroid Build Coastguard Worker return VT != MVT::f128; 199*9880d681SAndroid Build Coastguard Worker } 200*9880d681SAndroid Build Coastguard Worker shouldInsertFencesForAtomic(const Instruction * I)201*9880d681SAndroid Build Coastguard Worker bool shouldInsertFencesForAtomic(const Instruction *I) const override { 202*9880d681SAndroid Build Coastguard Worker // FIXME: We insert fences for each atomics and generate 203*9880d681SAndroid Build Coastguard Worker // sub-optimal code for PSO/TSO. (Approximately nobody uses any 204*9880d681SAndroid Build Coastguard Worker // mode but TSO, which makes this even more silly) 205*9880d681SAndroid Build Coastguard Worker return true; 206*9880d681SAndroid Build Coastguard Worker } 207*9880d681SAndroid Build Coastguard Worker 208*9880d681SAndroid Build Coastguard Worker AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 209*9880d681SAndroid Build Coastguard Worker 210*9880d681SAndroid Build Coastguard Worker void ReplaceNodeResults(SDNode *N, 211*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue>& Results, 212*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const override; 213*9880d681SAndroid Build Coastguard Worker 214*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB, 215*9880d681SAndroid Build Coastguard Worker unsigned BROpcode) const; 216*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 217*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB) const; 218*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 219*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB) const; 220*9880d681SAndroid Build Coastguard Worker }; 221*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker #endif // SPARC_ISELLOWERING_H 224