1 //==-- AArch64ISelLowering.h - AArch64 DAG Lowering Interface ----*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the interfaces that AArch64 uses to lower LLVM code into a 11 // selection DAG. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TARGET_AArch64_ISELLOWERING_H 16 #define LLVM_TARGET_AArch64_ISELLOWERING_H 17 18 #include "llvm/CodeGen/CallingConvLower.h" 19 #include "llvm/CodeGen/SelectionDAG.h" 20 #include "llvm/IR/CallingConv.h" 21 #include "llvm/Target/TargetLowering.h" 22 23 namespace llvm { 24 25 namespace AArch64ISD { 26 27 enum { 28 FIRST_NUMBER = ISD::BUILTIN_OP_END, 29 WrapperLarge, // 4-instruction MOVZ/MOVK sequence for 64-bit addresses. 30 CALL, // Function call. 31 32 // Almost the same as a normal call node, except that a TLSDesc relocation is 33 // needed so the linker can relax it correctly if possible. 34 TLSDESC_CALL, 35 ADRP, // Page address of a TargetGlobalAddress operand. 36 ADDlow, // Add the low 12 bits of a TargetGlobalAddress operand. 37 LOADgot, // Load from automatically generated descriptor (e.g. Global 38 // Offset Table, TLS record). 39 RET_FLAG, // Return with a flag operand. Operand 0 is the chain operand. 40 BRCOND, // Conditional branch instruction; "b.cond". 41 CSEL, 42 FCSEL, // Conditional move instruction. 43 CSINV, // Conditional select invert. 44 CSNEG, // Conditional select negate. 45 CSINC, // Conditional select increment. 46 47 // Pointer to the thread's local storage area. Materialised from TPIDR_EL0 on 48 // ELF. 49 THREAD_POINTER, 50 ADC, 51 SBC, // adc, sbc instructions 52 53 // Arithmetic instructions which write flags. 54 ADDS, 55 SUBS, 56 ADCS, 57 SBCS, 58 ANDS, 59 60 // Floating point comparison 61 FCMP, 62 63 // Floating point max and min instructions. 64 FMAX, 65 FMIN, 66 67 // Scalar extract 68 EXTR, 69 70 // Scalar-to-vector duplication 71 DUP, 72 DUPLANE8, 73 DUPLANE16, 74 DUPLANE32, 75 DUPLANE64, 76 77 // Vector immedate moves 78 MOVI, 79 MOVIshift, 80 MOVIedit, 81 MOVImsl, 82 FMOV, 83 MVNIshift, 84 MVNImsl, 85 86 // Vector immediate ops 87 BICi, 88 ORRi, 89 90 // Vector bit select: similar to ISD::VSELECT but not all bits within an 91 // element must be identical. 92 BSL, 93 94 // Vector arithmetic negation 95 NEG, 96 97 // Vector shuffles 98 ZIP1, 99 ZIP2, 100 UZP1, 101 UZP2, 102 TRN1, 103 TRN2, 104 REV16, 105 REV32, 106 REV64, 107 EXT, 108 109 // Vector shift by scalar 110 VSHL, 111 VLSHR, 112 VASHR, 113 114 // Vector shift by scalar (again) 115 SQSHL_I, 116 UQSHL_I, 117 SQSHLU_I, 118 SRSHR_I, 119 URSHR_I, 120 121 // Vector comparisons 122 CMEQ, 123 CMGE, 124 CMGT, 125 CMHI, 126 CMHS, 127 FCMEQ, 128 FCMGE, 129 FCMGT, 130 131 // Vector zero comparisons 132 CMEQz, 133 CMGEz, 134 CMGTz, 135 CMLEz, 136 CMLTz, 137 FCMEQz, 138 FCMGEz, 139 FCMGTz, 140 FCMLEz, 141 FCMLTz, 142 143 // Vector bitwise negation 144 NOT, 145 146 // Vector bitwise selection 147 BIT, 148 149 // Compare-and-branch 150 CBZ, 151 CBNZ, 152 TBZ, 153 TBNZ, 154 155 // Tail calls 156 TC_RETURN, 157 158 // Custom prefetch handling 159 PREFETCH, 160 161 // {s|u}int to FP within a FP register. 162 SITOF, 163 UITOF, 164 165 // NEON Load/Store with post-increment base updates 166 LD2post = ISD::FIRST_TARGET_MEMORY_OPCODE, 167 LD3post, 168 LD4post, 169 ST2post, 170 ST3post, 171 ST4post, 172 LD1x2post, 173 LD1x3post, 174 LD1x4post, 175 ST1x2post, 176 ST1x3post, 177 ST1x4post, 178 LD1DUPpost, 179 LD2DUPpost, 180 LD3DUPpost, 181 LD4DUPpost, 182 LD1LANEpost, 183 LD2LANEpost, 184 LD3LANEpost, 185 LD4LANEpost, 186 ST2LANEpost, 187 ST3LANEpost, 188 ST4LANEpost 189 }; 190 191 } // end namespace AArch64ISD 192 193 class AArch64Subtarget; 194 class AArch64TargetMachine; 195 196 class AArch64TargetLowering : public TargetLowering { 197 bool RequireStrictAlign; 198 199 public: 200 explicit AArch64TargetLowering(TargetMachine &TM); 201 202 /// Selects the correct CCAssignFn for a the given CallingConvention 203 /// value. 204 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; 205 206 /// computeKnownBitsForTargetNode - Determine which of the bits specified in 207 /// Mask are known to be either zero or one and return them in the 208 /// KnownZero/KnownOne bitsets. 209 void computeKnownBitsForTargetNode(const SDValue Op, APInt &KnownZero, 210 APInt &KnownOne, const SelectionDAG &DAG, 211 unsigned Depth = 0) const override; 212 213 MVT getScalarShiftAmountTy(EVT LHSTy) const override; 214 215 /// allowsUnalignedMemoryAccesses - Returns true if the target allows 216 /// unaligned memory accesses. of the specified type. 217 bool allowsUnalignedMemoryAccesses(EVT VT, unsigned AddrSpace = 0, 218 bool *Fast = nullptr) const override { 219 if (RequireStrictAlign) 220 return false; 221 // FIXME: True for Cyclone, but not necessary others. 222 if (Fast) 223 *Fast = true; 224 return true; 225 } 226 227 /// LowerOperation - Provide custom lowering hooks for some operations. 228 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 229 230 const char *getTargetNodeName(unsigned Opcode) const override; 231 232 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 233 234 /// getFunctionAlignment - Return the Log2 alignment of this function. 235 unsigned getFunctionAlignment(const Function *F) const; 236 237 /// getMaximalGlobalOffset - Returns the maximal possible offset which can 238 /// be used for loads / stores from the global. 239 unsigned getMaximalGlobalOffset() const override; 240 241 /// Returns true if a cast between SrcAS and DestAS is a noop. isNoopAddrSpaceCast(unsigned SrcAS,unsigned DestAS)242 bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override { 243 // Addrspacecasts are always noops. 244 return true; 245 } 246 247 /// createFastISel - This method returns a target specific FastISel object, 248 /// or null if the target does not support "fast" ISel. 249 FastISel *createFastISel(FunctionLoweringInfo &funcInfo, 250 const TargetLibraryInfo *libInfo) const override; 251 252 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 253 254 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override; 255 256 /// isShuffleMaskLegal - Return true if the given shuffle mask can be 257 /// codegen'd directly, or if it should be stack expanded. 258 bool isShuffleMaskLegal(const SmallVectorImpl<int> &M, EVT VT) const override; 259 260 /// getSetCCResultType - Return the ISD::SETCC ValueType 261 EVT getSetCCResultType(LLVMContext &Context, EVT VT) const override; 262 263 SDValue ReconstructShuffle(SDValue Op, SelectionDAG &DAG) const; 264 265 MachineBasicBlock *EmitF128CSEL(MachineInstr *MI, 266 MachineBasicBlock *BB) const; 267 268 MachineBasicBlock * 269 EmitInstrWithCustomInserter(MachineInstr *MI, 270 MachineBasicBlock *MBB) const override; 271 272 bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, 273 unsigned Intrinsic) const override; 274 275 bool isTruncateFree(Type *Ty1, Type *Ty2) const override; 276 bool isTruncateFree(EVT VT1, EVT VT2) const override; 277 278 bool isZExtFree(Type *Ty1, Type *Ty2) const override; 279 bool isZExtFree(EVT VT1, EVT VT2) const override; 280 bool isZExtFree(SDValue Val, EVT VT2) const override; 281 282 bool hasPairedLoad(Type *LoadedType, 283 unsigned &RequiredAligment) const override; 284 bool hasPairedLoad(EVT LoadedType, unsigned &RequiredAligment) const override; 285 286 bool isLegalAddImmediate(int64_t) const override; 287 bool isLegalICmpImmediate(int64_t) const override; 288 289 EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, unsigned SrcAlign, 290 bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc, 291 MachineFunction &MF) const override; 292 293 /// isLegalAddressingMode - Return true if the addressing mode represented 294 /// by AM is legal for this target, for a load/store of the specified type. 295 bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override; 296 297 /// \brief Return the cost of the scaling factor used in the addressing 298 /// mode represented by AM for this target, for a load/store 299 /// of the specified type. 300 /// If the AM is supported, the return value must be >= 0. 301 /// If the AM is not supported, it returns a negative value. 302 int getScalingFactorCost(const AddrMode &AM, Type *Ty) const override; 303 304 /// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster 305 /// than a pair of fmul and fadd instructions. fmuladd intrinsics will be 306 /// expanded to FMAs when this method returns true, otherwise fmuladd is 307 /// expanded to fmul + fadd. 308 bool isFMAFasterThanFMulAndFAdd(EVT VT) const override; 309 310 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override; 311 312 /// \brief Returns false if N is a bit extraction pattern of (X >> C) & Mask. 313 bool isDesirableToCommuteWithShift(const SDNode *N) const override; 314 315 /// \brief Returns true if it is beneficial to convert a load of a constant 316 /// to just the constant itself. 317 bool shouldConvertConstantLoadToIntImm(const APInt &Imm, 318 Type *Ty) const override; 319 320 Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, 321 AtomicOrdering Ord) const override; 322 Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val, 323 Value *Addr, AtomicOrdering Ord) const override; 324 325 bool shouldExpandAtomicInIR(Instruction *Inst) const override; 326 327 TargetLoweringBase::LegalizeTypeAction 328 getPreferredVectorAction(EVT VT) const override; 329 330 private: 331 /// Subtarget - Keep a pointer to the AArch64Subtarget around so that we can 332 /// make the right decision when generating code for different targets. 333 const AArch64Subtarget *Subtarget; 334 335 void addTypeForNEON(EVT VT, EVT PromotedBitwiseVT); 336 void addDRTypeForNEON(MVT VT); 337 void addQRTypeForNEON(MVT VT); 338 339 SDValue 340 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 341 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc DL, 342 SelectionDAG &DAG, 343 SmallVectorImpl<SDValue> &InVals) const override; 344 345 SDValue LowerCall(CallLoweringInfo & /*CLI*/, 346 SmallVectorImpl<SDValue> &InVals) const override; 347 348 SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 349 CallingConv::ID CallConv, bool isVarArg, 350 const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc DL, 351 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, 352 bool isThisReturn, SDValue ThisVal) const; 353 354 bool isEligibleForTailCallOptimization( 355 SDValue Callee, CallingConv::ID CalleeCC, bool isVarArg, 356 bool isCalleeStructRet, bool isCallerStructRet, 357 const SmallVectorImpl<ISD::OutputArg> &Outs, 358 const SmallVectorImpl<SDValue> &OutVals, 359 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const; 360 361 /// Finds the incoming stack arguments which overlap the given fixed stack 362 /// object and incorporates their load into the current chain. This prevents 363 /// an upcoming store from clobbering the stack argument before it's used. 364 SDValue addTokenForArgument(SDValue Chain, SelectionDAG &DAG, 365 MachineFrameInfo *MFI, int ClobberedFI) const; 366 367 bool DoesCalleeRestoreStack(CallingConv::ID CallCC, bool TailCallOpt) const; 368 369 bool IsTailCallConvention(CallingConv::ID CallCC) const; 370 371 void saveVarArgRegisters(CCState &CCInfo, SelectionDAG &DAG, SDLoc DL, 372 SDValue &Chain) const; 373 374 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 375 bool isVarArg, 376 const SmallVectorImpl<ISD::OutputArg> &Outs, 377 LLVMContext &Context) const override; 378 379 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 380 const SmallVectorImpl<ISD::OutputArg> &Outs, 381 const SmallVectorImpl<SDValue> &OutVals, SDLoc DL, 382 SelectionDAG &DAG) const override; 383 384 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 385 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 386 SDValue LowerDarwinGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 387 SDValue LowerELFGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 388 SDValue LowerELFTLSDescCall(SDValue SymAddr, SDValue DescAddr, SDLoc DL, 389 SelectionDAG &DAG) const; 390 SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 391 SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; 392 SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; 393 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 394 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 395 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 396 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 397 SDValue LowerAAPCS_VASTART(SDValue Op, SelectionDAG &DAG) const; 398 SDValue LowerDarwin_VASTART(SDValue Op, SelectionDAG &DAG) const; 399 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 400 SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const; 401 SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; 402 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 403 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 404 SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 405 SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 406 SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const; 407 SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 408 SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; 409 SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const; 410 SDValue LowerVectorSRA_SRL_SHL(SDValue Op, SelectionDAG &DAG) const; 411 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 412 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG) const; 413 SDValue LowerVSETCC(SDValue Op, SelectionDAG &DAG) const; 414 SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const; 415 SDValue LowerF128Call(SDValue Op, SelectionDAG &DAG, 416 RTLIB::Libcall Call) const; 417 SDValue LowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const; 418 SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const; 419 SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const; 420 SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const; 421 SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 422 SDValue LowerVectorAND(SDValue Op, SelectionDAG &DAG) const; 423 SDValue LowerVectorOR(SDValue Op, SelectionDAG &DAG) const; 424 SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const; 425 SDValue LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const; 426 427 ConstraintType 428 getConstraintType(const std::string &Constraint) const override; 429 unsigned getRegisterByName(const char* RegName, EVT VT) const override; 430 431 /// Examine constraint string and operand type and determine a weight value. 432 /// The operand object must already have been set up with the operand type. 433 ConstraintWeight 434 getSingleConstraintMatchWeight(AsmOperandInfo &info, 435 const char *constraint) const override; 436 437 std::pair<unsigned, const TargetRegisterClass *> 438 getRegForInlineAsmConstraint(const std::string &Constraint, 439 MVT VT) const override; 440 void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, 441 std::vector<SDValue> &Ops, 442 SelectionDAG &DAG) const override; 443 444 bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override; 445 bool mayBeEmittedAsTailCall(CallInst *CI) const override; 446 bool getIndexedAddressParts(SDNode *Op, SDValue &Base, SDValue &Offset, 447 ISD::MemIndexedMode &AM, bool &IsInc, 448 SelectionDAG &DAG) const; 449 bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, 450 ISD::MemIndexedMode &AM, 451 SelectionDAG &DAG) const override; 452 bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, 453 SDValue &Offset, ISD::MemIndexedMode &AM, 454 SelectionDAG &DAG) const override; 455 456 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, 457 SelectionDAG &DAG) const override; 458 }; 459 460 namespace AArch64 { 461 FastISel *createFastISel(FunctionLoweringInfo &funcInfo, 462 const TargetLibraryInfo *libInfo); 463 } // end namespace AArch64 464 465 } // end namespace llvm 466 467 #endif // LLVM_TARGET_AArch64_ISELLOWERING_H 468