MipsISelLowering.h revision 7d71209912bb55856f34df7013382e6dd310983b
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===-- MipsISelLowering.h - Mips DAG Lowering Interface --------*- C++ -*-===// 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The LLVM Compiler Infrastructure 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// License. See LICENSE.TXT for details. 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===// 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This file defines the interfaces that Mips uses to lower LLVM code into a 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// selection DAG. 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===// 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef MipsISELLOWERING_H 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MipsISELLOWERING_H 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "Mips.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "MipsSubtarget.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/CodeGen/CallingConvLower.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/CodeGen/SelectionDAG.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/Target/TargetLowering.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace llvm { 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) namespace MipsISD { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enum NodeType { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Start the numbering from where ISD NodeType finishes. 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FIRST_NUMBER = ISD::BUILTIN_OP_END, 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Jump and link (call) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) JmpLink, 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Tail call 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TailCall, 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Get the Higher 16 bits from a 32-bit immediate 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No relation with Mips Hi register 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Hi, 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Get the Lower 16 bits from a 32-bit immediate 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No relation with Mips Lo register 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Lo, 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Handle gp_rel (small data/bss sections) relocation. 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GPRel, 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Thread Pointer 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ThreadPointer, 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Floating Point Branch Conditional 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FPBrcond, 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Floating Point Compare 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FPCmp, 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Floating Point Conditional Moves 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CMovFP_T, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CMovFP_F, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Floating Point Rounding 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FPRound, 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Return 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Ret, 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // MAdd/Sub nodes 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MAdd, 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MAddu, 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MSub, 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MSubu, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // DivRem(u) 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DivRem, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DivRemU, 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 76 BuildPairF64, 77 ExtractElementF64, 78 79 Wrapper, 80 81 DynAlloc, 82 83 Sync, 84 85 Ext, 86 Ins, 87 88 // EXTR.W instrinsic nodes. 89 EXTP, 90 EXTPDP, 91 EXTR_S_H, 92 EXTR_W, 93 EXTR_R_W, 94 EXTR_RS_W, 95 SHILO, 96 MTHLIP, 97 98 // DPA.W intrinsic nodes. 99 MULSAQ_S_W_PH, 100 MAQ_S_W_PHL, 101 MAQ_S_W_PHR, 102 MAQ_SA_W_PHL, 103 MAQ_SA_W_PHR, 104 DPAU_H_QBL, 105 DPAU_H_QBR, 106 DPSU_H_QBL, 107 DPSU_H_QBR, 108 DPAQ_S_W_PH, 109 DPSQ_S_W_PH, 110 DPAQ_SA_L_W, 111 DPSQ_SA_L_W, 112 DPA_W_PH, 113 DPS_W_PH, 114 DPAQX_S_W_PH, 115 DPAQX_SA_W_PH, 116 DPAX_W_PH, 117 DPSX_W_PH, 118 DPSQX_S_W_PH, 119 DPSQX_SA_W_PH, 120 MULSA_W_PH, 121 122 MULT, 123 MULTU, 124 MADD_DSP, 125 MADDU_DSP, 126 MSUB_DSP, 127 MSUBU_DSP, 128 129 // Load/Store Left/Right nodes. 130 LWL = ISD::FIRST_TARGET_MEMORY_OPCODE, 131 LWR, 132 SWL, 133 SWR, 134 LDL, 135 LDR, 136 SDL, 137 SDR 138 }; 139 } 140 141 //===--------------------------------------------------------------------===// 142 // TargetLowering Implementation 143 //===--------------------------------------------------------------------===// 144 145 class MipsTargetLowering : public TargetLowering { 146 public: 147 explicit MipsTargetLowering(MipsTargetMachine &TM); 148 149 virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; } 150 151 virtual bool allowsUnalignedMemoryAccesses (EVT VT) const; 152 153 virtual void LowerOperationWrapper(SDNode *N, 154 SmallVectorImpl<SDValue> &Results, 155 SelectionDAG &DAG) const; 156 157 /// LowerOperation - Provide custom lowering hooks for some operations. 158 virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const; 159 160 /// ReplaceNodeResults - Replace the results of node with an illegal result 161 /// type with new values built out of custom code. 162 /// 163 virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, 164 SelectionDAG &DAG) const; 165 166 /// getTargetNodeName - This method returns the name of a target specific 167 // DAG node. 168 virtual const char *getTargetNodeName(unsigned Opcode) const; 169 170 /// getSetCCResultType - get the ISD::SETCC result ValueType 171 EVT getSetCCResultType(EVT VT) const; 172 173 virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; 174 private: 175 176 /// ByValArgInfo - Byval argument information. 177 struct ByValArgInfo { 178 unsigned FirstIdx; // Index of the first register used. 179 unsigned NumRegs; // Number of registers used for this argument. 180 unsigned Address; // Offset of the stack area used to pass this argument. 181 182 ByValArgInfo() : FirstIdx(0), NumRegs(0), Address(0) {} 183 }; 184 185 /// MipsCC - This class provides methods used to analyze formal and call 186 /// arguments and inquire about calling convention information. 187 class MipsCC { 188 public: 189 MipsCC(CallingConv::ID CallConv, bool IsVarArg, bool IsO32, 190 CCState &Info); 191 192 void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs); 193 void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins); 194 void handleByValArg(unsigned ValNo, MVT ValVT, MVT LocVT, 195 CCValAssign::LocInfo LocInfo, 196 ISD::ArgFlagsTy ArgFlags); 197 198 const CCState &getCCInfo() const { return CCInfo; } 199 200 /// hasByValArg - Returns true if function has byval arguments. 201 bool hasByValArg() const { return !ByValArgs.empty(); } 202 203 /// useRegsForByval - Returns true if the calling convention allows the 204 /// use of registers to pass byval arguments. 205 bool useRegsForByval() const { return UseRegsForByval; } 206 207 /// regSize - Size (in number of bits) of integer registers. 208 unsigned regSize() const { return RegSize; } 209 210 /// numIntArgRegs - Number of integer registers available for calls. 211 unsigned numIntArgRegs() const { return NumIntArgRegs; } 212 213 /// reservedArgArea - The size of the area the caller reserves for 214 /// register arguments. This is 16-byte if ABI is O32. 215 unsigned reservedArgArea() const { return ReservedArgArea; } 216 217 /// intArgRegs - Pointer to array of integer registers. 218 const uint16_t *intArgRegs() const { return IntArgRegs; } 219 220 typedef SmallVector<ByValArgInfo, 2>::const_iterator byval_iterator; 221 byval_iterator byval_begin() const { return ByValArgs.begin(); } 222 byval_iterator byval_end() const { return ByValArgs.end(); } 223 224 private: 225 void allocateRegs(ByValArgInfo &ByVal, unsigned ByValSize, 226 unsigned Align); 227 228 CCState &CCInfo; 229 bool UseRegsForByval; 230 unsigned RegSize; 231 unsigned NumIntArgRegs; 232 unsigned ReservedArgArea; 233 const uint16_t *IntArgRegs, *ShadowRegs; 234 SmallVector<ByValArgInfo, 2> ByValArgs; 235 llvm::CCAssignFn *FixedFn, *VarFn; 236 }; 237 238 // Subtarget Info 239 const MipsSubtarget *Subtarget; 240 241 bool HasMips64, IsN64, IsO32; 242 243 // Lower Operand helpers 244 SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 245 CallingConv::ID CallConv, bool isVarArg, 246 const SmallVectorImpl<ISD::InputArg> &Ins, 247 DebugLoc dl, SelectionDAG &DAG, 248 SmallVectorImpl<SDValue> &InVals) const; 249 250 // Lower Operand specifics 251 SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; 252 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 253 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 254 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 255 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 256 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 257 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; 258 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 259 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 260 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 261 SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const; 262 SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) const; 263 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 264 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 265 SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG& DAG) const; 266 SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const; 267 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG& DAG) const; 268 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG& DAG, 269 bool IsSRA) const; 270 SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; 271 SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; 272 SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 273 SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const; 274 275 /// IsEligibleForTailCallOptimization - Check whether the call is eligible 276 /// for tail call optimization. 277 bool IsEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 278 bool IsVarArg, 279 unsigned NextStackOffset) const; 280 281 /// copyByValArg - Copy argument registers which were used to pass a byval 282 /// argument to the stack. Create a stack frame object for the byval 283 /// argument. 284 void copyByValRegs(SDValue Chain, DebugLoc DL, 285 std::vector<SDValue> &OutChains, SelectionDAG &DAG, 286 const ISD::ArgFlagsTy &Flags, 287 SmallVectorImpl<SDValue> &InVals, 288 const Argument *FuncArg, 289 const MipsCC &CC, const ByValArgInfo &ByVal) const; 290 291 /// passByValArg - Pass a byval argument in registers or on stack. 292 void passByValArg(SDValue Chain, DebugLoc DL, 293 SmallVector<std::pair<unsigned, SDValue>, 16> &RegsToPass, 294 SmallVector<SDValue, 8> &MemOpChains, SDValue StackPtr, 295 MachineFrameInfo *MFI, SelectionDAG &DAG, SDValue Arg, 296 const MipsCC &CC, const ByValArgInfo &ByVal, 297 const ISD::ArgFlagsTy &Flags, bool isLittle) const; 298 299 /// writeVarArgRegs - Write variable function arguments passed in registers 300 /// to the stack. Also create a stack frame object for the first variable 301 /// argument. 302 void writeVarArgRegs(std::vector<SDValue> &OutChains, const MipsCC &CC, 303 SDValue Chain, DebugLoc DL, SelectionDAG &DAG) const; 304 305 virtual SDValue 306 LowerFormalArguments(SDValue Chain, 307 CallingConv::ID CallConv, bool isVarArg, 308 const SmallVectorImpl<ISD::InputArg> &Ins, 309 DebugLoc dl, SelectionDAG &DAG, 310 SmallVectorImpl<SDValue> &InVals) const; 311 312 SDValue passArgOnStack(SDValue StackPtr, unsigned Offset, SDValue Chain, 313 SDValue Arg, DebugLoc DL, bool IsTailCall, 314 SelectionDAG &DAG) const; 315 316 virtual SDValue 317 LowerCall(TargetLowering::CallLoweringInfo &CLI, 318 SmallVectorImpl<SDValue> &InVals) const; 319 320 virtual bool 321 CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 322 bool isVarArg, 323 const SmallVectorImpl<ISD::OutputArg> &Outs, 324 LLVMContext &Context) const; 325 326 virtual SDValue 327 LowerReturn(SDValue Chain, 328 CallingConv::ID CallConv, bool isVarArg, 329 const SmallVectorImpl<ISD::OutputArg> &Outs, 330 const SmallVectorImpl<SDValue> &OutVals, 331 DebugLoc dl, SelectionDAG &DAG) const; 332 333 virtual MachineBasicBlock * 334 EmitInstrWithCustomInserter(MachineInstr *MI, 335 MachineBasicBlock *MBB) const; 336 337 // Inline asm support 338 ConstraintType getConstraintType(const std::string &Constraint) const; 339 340 /// Examine constraint string and operand type and determine a weight value. 341 /// The operand object must already have been set up with the operand type. 342 ConstraintWeight getSingleConstraintMatchWeight( 343 AsmOperandInfo &info, const char *constraint) const; 344 345 std::pair<unsigned, const TargetRegisterClass*> 346 getRegForInlineAsmConstraint(const std::string &Constraint, 347 EVT VT) const; 348 349 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops 350 /// vector. If it is invalid, don't add anything to Ops. If hasMemory is 351 /// true it means one of the asm constraint of the inline asm instruction 352 /// being processed is 'm'. 353 virtual void LowerAsmOperandForConstraint(SDValue Op, 354 std::string &Constraint, 355 std::vector<SDValue> &Ops, 356 SelectionDAG &DAG) const; 357 358 virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; 359 360 virtual EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, 361 unsigned SrcAlign, bool IsZeroVal, 362 bool MemcpyStrSrc, 363 MachineFunction &MF) const; 364 365 /// isFPImmLegal - Returns true if the target can instruction select the 366 /// specified FP immediate natively. If false, the legalizer will 367 /// materialize the FP immediate as a load from a constant pool. 368 virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const; 369 370 virtual unsigned getJumpTableEncoding() const; 371 372 MachineBasicBlock *EmitBPOSGE32(MachineInstr *MI, 373 MachineBasicBlock *BB) const; 374 MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, 375 unsigned Size, unsigned BinOpcode, bool Nand = false) const; 376 MachineBasicBlock *EmitAtomicBinaryPartword(MachineInstr *MI, 377 MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode, 378 bool Nand = false) const; 379 MachineBasicBlock *EmitAtomicCmpSwap(MachineInstr *MI, 380 MachineBasicBlock *BB, unsigned Size) const; 381 MachineBasicBlock *EmitAtomicCmpSwapPartword(MachineInstr *MI, 382 MachineBasicBlock *BB, unsigned Size) const; 383 }; 384} 385 386#endif // MipsISELLOWERING_H 387