109467b48Spatrick //===-- PPCISelLowering.h - PPC32 DAG Lowering Interface --------*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // This file defines the interfaces that PPC uses to lower LLVM code into a 1009467b48Spatrick // selection DAG. 1109467b48Spatrick // 1209467b48Spatrick //===----------------------------------------------------------------------===// 1309467b48Spatrick 1409467b48Spatrick #ifndef LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H 1509467b48Spatrick #define LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H 1609467b48Spatrick 1709467b48Spatrick #include "PPCInstrInfo.h" 1809467b48Spatrick #include "llvm/CodeGen/CallingConvLower.h" 1909467b48Spatrick #include "llvm/CodeGen/MachineFunction.h" 2009467b48Spatrick #include "llvm/CodeGen/MachineMemOperand.h" 2109467b48Spatrick #include "llvm/CodeGen/SelectionDAG.h" 2209467b48Spatrick #include "llvm/CodeGen/SelectionDAGNodes.h" 2309467b48Spatrick #include "llvm/CodeGen/TargetLowering.h" 2409467b48Spatrick #include "llvm/CodeGen/ValueTypes.h" 2509467b48Spatrick #include "llvm/IR/Attributes.h" 2609467b48Spatrick #include "llvm/IR/CallingConv.h" 2709467b48Spatrick #include "llvm/IR/Function.h" 2809467b48Spatrick #include "llvm/IR/InlineAsm.h" 2909467b48Spatrick #include "llvm/IR/Metadata.h" 3009467b48Spatrick #include "llvm/IR/Type.h" 3109467b48Spatrick #include "llvm/Support/MachineValueType.h" 32*d415bd75Srobert #include <optional> 3309467b48Spatrick #include <utility> 3409467b48Spatrick 3509467b48Spatrick namespace llvm { 3609467b48Spatrick 3709467b48Spatrick namespace PPCISD { 3809467b48Spatrick 3909467b48Spatrick // When adding a NEW PPCISD node please add it to the correct position in 4009467b48Spatrick // the enum. The order of elements in this enum matters! 4109467b48Spatrick // Values that are added after this entry: 4209467b48Spatrick // STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE 4309467b48Spatrick // are considered memory opcodes and are treated differently than entries 4409467b48Spatrick // that come before it. For example, ADD or MUL should be placed before 4509467b48Spatrick // the ISD::FIRST_TARGET_MEMORY_OPCODE while a LOAD or STORE should come 4609467b48Spatrick // after it. 4709467b48Spatrick enum NodeType : unsigned { 4809467b48Spatrick // Start the numbering where the builtin ops and target ops leave off. 4909467b48Spatrick FIRST_NUMBER = ISD::BUILTIN_OP_END, 5009467b48Spatrick 5109467b48Spatrick /// FSEL - Traditional three-operand fsel node. 5209467b48Spatrick /// 5309467b48Spatrick FSEL, 5409467b48Spatrick 55*d415bd75Srobert /// XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions. 56*d415bd75Srobert XSMAXC, 57*d415bd75Srobert XSMINC, 5809467b48Spatrick 5909467b48Spatrick /// FCFID - The FCFID instruction, taking an f64 operand and producing 6009467b48Spatrick /// and f64 value containing the FP representation of the integer that 6109467b48Spatrick /// was temporarily in the f64 operand. 6209467b48Spatrick FCFID, 6309467b48Spatrick 6409467b48Spatrick /// Newer FCFID[US] integer-to-floating-point conversion instructions for 6509467b48Spatrick /// unsigned integers and single-precision outputs. 6609467b48Spatrick FCFIDU, 6709467b48Spatrick FCFIDS, 6809467b48Spatrick FCFIDUS, 6909467b48Spatrick 7009467b48Spatrick /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 7109467b48Spatrick /// operand, producing an f64 value containing the integer representation 7209467b48Spatrick /// of that FP value. 7309467b48Spatrick FCTIDZ, 7409467b48Spatrick FCTIWZ, 7509467b48Spatrick 7609467b48Spatrick /// Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for 7709467b48Spatrick /// unsigned integers with round toward zero. 7809467b48Spatrick FCTIDUZ, 7909467b48Spatrick FCTIWUZ, 8009467b48Spatrick 81*d415bd75Srobert /// Floating-point-to-integer conversion instructions 8209467b48Spatrick FP_TO_UINT_IN_VSR, 8309467b48Spatrick FP_TO_SINT_IN_VSR, 8409467b48Spatrick 8509467b48Spatrick /// VEXTS, ByteWidth - takes an input in VSFRC and produces an output in 8609467b48Spatrick /// VSFRC that is sign-extended from ByteWidth to a 64-byte integer. 8709467b48Spatrick VEXTS, 8809467b48Spatrick 8909467b48Spatrick /// Reciprocal estimate instructions (unary FP ops). 9009467b48Spatrick FRE, 9109467b48Spatrick FRSQRTE, 9209467b48Spatrick 9373471bf0Spatrick /// Test instruction for software square root. 9473471bf0Spatrick FTSQRT, 9573471bf0Spatrick 9673471bf0Spatrick /// Square root instruction. 9773471bf0Spatrick FSQRT, 9873471bf0Spatrick 9909467b48Spatrick /// VPERM - The PPC VPERM Instruction. 10009467b48Spatrick /// 10109467b48Spatrick VPERM, 10209467b48Spatrick 10309467b48Spatrick /// XXSPLT - The PPC VSX splat instructions 10409467b48Spatrick /// 10509467b48Spatrick XXSPLT, 10609467b48Spatrick 107097a140dSpatrick /// XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for 108097a140dSpatrick /// converting immediate single precision numbers to double precision 109097a140dSpatrick /// vector or scalar. 110097a140dSpatrick XXSPLTI_SP_TO_DP, 111097a140dSpatrick 112097a140dSpatrick /// XXSPLTI32DX - The PPC XXSPLTI32DX instruction. 113097a140dSpatrick /// 114097a140dSpatrick XXSPLTI32DX, 115097a140dSpatrick 11609467b48Spatrick /// VECINSERT - The PPC vector insert instruction 11709467b48Spatrick /// 11809467b48Spatrick VECINSERT, 11909467b48Spatrick 12009467b48Spatrick /// VECSHL - The PPC vector shift left instruction 12109467b48Spatrick /// 12209467b48Spatrick VECSHL, 12309467b48Spatrick 12409467b48Spatrick /// XXPERMDI - The PPC XXPERMDI instruction 12509467b48Spatrick /// 12609467b48Spatrick XXPERMDI, 127*d415bd75Srobert XXPERM, 12809467b48Spatrick 12909467b48Spatrick /// The CMPB instruction (takes two operands of i32 or i64). 13009467b48Spatrick CMPB, 13109467b48Spatrick 13209467b48Spatrick /// Hi/Lo - These represent the high and low 16-bit parts of a global 13309467b48Spatrick /// address respectively. These nodes have two operands, the first of 13409467b48Spatrick /// which must be a TargetGlobalAddress, and the second of which must be a 13509467b48Spatrick /// Constant. Selected naively, these turn into 'lis G+C' and 'li G+C', 13609467b48Spatrick /// though these are usually folded into other nodes. 13709467b48Spatrick Hi, 13809467b48Spatrick Lo, 13909467b48Spatrick 14009467b48Spatrick /// The following two target-specific nodes are used for calls through 14109467b48Spatrick /// function pointers in the 64-bit SVR4 ABI. 14209467b48Spatrick 14309467b48Spatrick /// OPRC, CHAIN = DYNALLOC(CHAIN, NEGSIZE, FRAME_INDEX) 14409467b48Spatrick /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to 14509467b48Spatrick /// compute an allocation on the stack. 14609467b48Spatrick DYNALLOC, 14709467b48Spatrick 14809467b48Spatrick /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to 14909467b48Spatrick /// compute an offset from native SP to the address of the most recent 15009467b48Spatrick /// dynamic alloca. 15109467b48Spatrick DYNAREAOFFSET, 15209467b48Spatrick 153097a140dSpatrick /// To avoid stack clash, allocation is performed by block and each block is 154097a140dSpatrick /// probed. 155097a140dSpatrick PROBED_ALLOCA, 156097a140dSpatrick 15773471bf0Spatrick /// The result of the mflr at function entry, used for PIC code. 15809467b48Spatrick GlobalBaseReg, 15909467b48Spatrick 16009467b48Spatrick /// These nodes represent PPC shifts. 16109467b48Spatrick /// 16209467b48Spatrick /// For scalar types, only the last `n + 1` bits of the shift amounts 16309467b48Spatrick /// are used, where n is log2(sizeof(element) * 8). See sld/slw, etc. 16409467b48Spatrick /// for exact behaviors. 16509467b48Spatrick /// 16609467b48Spatrick /// For vector types, only the last n bits are used. See vsld. 16709467b48Spatrick SRL, 16809467b48Spatrick SRA, 16909467b48Spatrick SHL, 17009467b48Spatrick 171097a140dSpatrick /// FNMSUB - Negated multiply-subtract instruction. 172097a140dSpatrick FNMSUB, 173097a140dSpatrick 17409467b48Spatrick /// EXTSWSLI = The PPC extswsli instruction, which does an extend-sign 17509467b48Spatrick /// word and shift left immediate. 17609467b48Spatrick EXTSWSLI, 17709467b48Spatrick 17809467b48Spatrick /// The combination of sra[wd]i and addze used to implemented signed 17909467b48Spatrick /// integer division by a power of 2. The first operand is the dividend, 18009467b48Spatrick /// and the second is the constant shift amount (representing the 18109467b48Spatrick /// divisor). 18209467b48Spatrick SRA_ADDZE, 18309467b48Spatrick 18409467b48Spatrick /// CALL - A direct function call. 18509467b48Spatrick /// CALL_NOP is a call with the special NOP which follows 64-bit 186097a140dSpatrick /// CALL_NOTOC the caller does not use the TOC. 18709467b48Spatrick /// SVR4 calls and 32-bit/64-bit AIX calls. 18809467b48Spatrick CALL, 18909467b48Spatrick CALL_NOP, 190097a140dSpatrick CALL_NOTOC, 19109467b48Spatrick 19209467b48Spatrick /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a 19309467b48Spatrick /// MTCTR instruction. 19409467b48Spatrick MTCTR, 19509467b48Spatrick 19609467b48Spatrick /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a 19709467b48Spatrick /// BCTRL instruction. 19809467b48Spatrick BCTRL, 19909467b48Spatrick 20009467b48Spatrick /// CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl 20109467b48Spatrick /// instruction and the TOC reload required on 64-bit ELF, 32-bit AIX 20209467b48Spatrick /// and 64-bit AIX. 20309467b48Spatrick BCTRL_LOAD_TOC, 20409467b48Spatrick 205*d415bd75Srobert /// The variants that implicitly define rounding mode for calls with 206*d415bd75Srobert /// strictfp semantics. 207*d415bd75Srobert CALL_RM, 208*d415bd75Srobert CALL_NOP_RM, 209*d415bd75Srobert CALL_NOTOC_RM, 210*d415bd75Srobert BCTRL_RM, 211*d415bd75Srobert BCTRL_LOAD_TOC_RM, 212*d415bd75Srobert 21309467b48Spatrick /// Return with a flag operand, matched by 'blr' 21409467b48Spatrick RET_FLAG, 21509467b48Spatrick 21609467b48Spatrick /// R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction. 21709467b48Spatrick /// This copies the bits corresponding to the specified CRREG into the 21809467b48Spatrick /// resultant GPR. Bits corresponding to other CR regs are undefined. 21909467b48Spatrick MFOCRF, 22009467b48Spatrick 22109467b48Spatrick /// Direct move from a VSX register to a GPR 22209467b48Spatrick MFVSR, 22309467b48Spatrick 22409467b48Spatrick /// Direct move from a GPR to a VSX register (algebraic) 22509467b48Spatrick MTVSRA, 22609467b48Spatrick 22709467b48Spatrick /// Direct move from a GPR to a VSX register (zero) 22809467b48Spatrick MTVSRZ, 22909467b48Spatrick 23009467b48Spatrick /// Direct move of 2 consecutive GPR to a VSX register. 23109467b48Spatrick BUILD_FP128, 23209467b48Spatrick 23309467b48Spatrick /// BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and 23409467b48Spatrick /// EXTRACT_ELEMENT but take f64 arguments instead of i64, as i64 is 23509467b48Spatrick /// unsupported for this target. 23609467b48Spatrick /// Merge 2 GPRs to a single SPE register. 23709467b48Spatrick BUILD_SPE64, 23809467b48Spatrick 23909467b48Spatrick /// Extract SPE register component, second argument is high or low. 24009467b48Spatrick EXTRACT_SPE, 24109467b48Spatrick 24209467b48Spatrick /// Extract a subvector from signed integer vector and convert to FP. 24309467b48Spatrick /// It is primarily used to convert a (widened) illegal integer vector 24409467b48Spatrick /// type to a legal floating point vector type. 24509467b48Spatrick /// For example v2i32 -> widened to v4i32 -> v2f64 24609467b48Spatrick SINT_VEC_TO_FP, 24709467b48Spatrick 24809467b48Spatrick /// Extract a subvector from unsigned integer vector and convert to FP. 24909467b48Spatrick /// As with SINT_VEC_TO_FP, used for converting illegal types. 25009467b48Spatrick UINT_VEC_TO_FP, 25109467b48Spatrick 252097a140dSpatrick /// PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to 253097a140dSpatrick /// place the value into the least significant element of the most 254097a140dSpatrick /// significant doubleword in the vector. This is not element zero for 255097a140dSpatrick /// anything smaller than a doubleword on either endianness. This node has 256097a140dSpatrick /// the same semantics as SCALAR_TO_VECTOR except that the value remains in 257097a140dSpatrick /// the aforementioned location in the vector register. 258097a140dSpatrick SCALAR_TO_VECTOR_PERMUTED, 259097a140dSpatrick 26009467b48Spatrick // FIXME: Remove these once the ANDI glue bug is fixed: 26109467b48Spatrick /// i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the 26209467b48Spatrick /// eq or gt bit of CR0 after executing andi. x, 1. This is used to 26309467b48Spatrick /// implement truncation of i32 or i64 to i1. 26409467b48Spatrick ANDI_rec_1_EQ_BIT, 26509467b48Spatrick ANDI_rec_1_GT_BIT, 26609467b48Spatrick 26709467b48Spatrick // READ_TIME_BASE - A read of the 64-bit time-base register on a 32-bit 26809467b48Spatrick // target (returns (Lo, Hi)). It takes a chain operand. 26909467b48Spatrick READ_TIME_BASE, 27009467b48Spatrick 27109467b48Spatrick // EH_SJLJ_SETJMP - SjLj exception handling setjmp. 27209467b48Spatrick EH_SJLJ_SETJMP, 27309467b48Spatrick 27409467b48Spatrick // EH_SJLJ_LONGJMP - SjLj exception handling longjmp. 27509467b48Spatrick EH_SJLJ_LONGJMP, 27609467b48Spatrick 27709467b48Spatrick /// RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* 27809467b48Spatrick /// instructions. For lack of better number, we use the opcode number 27909467b48Spatrick /// encoding for the OPC field to identify the compare. For example, 838 28009467b48Spatrick /// is VCMPGTSH. 28109467b48Spatrick VCMP, 28209467b48Spatrick 28373471bf0Spatrick /// RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the 28473471bf0Spatrick /// altivec VCMP*_rec instructions. For lack of better number, we use the 28509467b48Spatrick /// opcode number encoding for the OPC field to identify the compare. For 28609467b48Spatrick /// example, 838 is VCMPGTSH. 28773471bf0Spatrick VCMP_rec, 28809467b48Spatrick 28909467b48Spatrick /// CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This 29009467b48Spatrick /// corresponds to the COND_BRANCH pseudo instruction. CRRC is the 29109467b48Spatrick /// condition register to branch on, OPC is the branch opcode to use (e.g. 29209467b48Spatrick /// PPC::BLE), DESTBB is the destination block to branch to, and INFLAG is 29309467b48Spatrick /// an optional input flag argument. 29409467b48Spatrick COND_BRANCH, 29509467b48Spatrick 29609467b48Spatrick /// CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based 29709467b48Spatrick /// loops. 29809467b48Spatrick BDNZ, 29909467b48Spatrick BDZ, 30009467b48Spatrick 30109467b48Spatrick /// F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding 30209467b48Spatrick /// towards zero. Used only as part of the long double-to-int 30309467b48Spatrick /// conversion sequence. 30409467b48Spatrick FADDRTZ, 30509467b48Spatrick 30609467b48Spatrick /// F8RC = MFFS - This moves the FPSCR (not modeled) into the register. 30709467b48Spatrick MFFS, 30809467b48Spatrick 30909467b48Spatrick /// TC_RETURN - A tail call return. 31009467b48Spatrick /// operand #0 chain 31109467b48Spatrick /// operand #1 callee (register or absolute) 31209467b48Spatrick /// operand #2 stack adjustment 31309467b48Spatrick /// operand #3 optional in flag 31409467b48Spatrick TC_RETURN, 31509467b48Spatrick 31609467b48Spatrick /// ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls 31709467b48Spatrick CR6SET, 31809467b48Spatrick CR6UNSET, 31909467b48Spatrick 32009467b48Spatrick /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by initial-exec TLS 32109467b48Spatrick /// for non-position independent code on PPC32. 32209467b48Spatrick PPC32_GOT, 32309467b48Spatrick 32409467b48Spatrick /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and 32509467b48Spatrick /// local dynamic TLS and position indendepent code on PPC32. 32609467b48Spatrick PPC32_PICGOT, 32709467b48Spatrick 32809467b48Spatrick /// G8RC = ADDIS_GOT_TPREL_HA %x2, Symbol - Used by the initial-exec 32909467b48Spatrick /// TLS model, produces an ADDIS8 instruction that adds the GOT 33009467b48Spatrick /// base to sym\@got\@tprel\@ha. 33109467b48Spatrick ADDIS_GOT_TPREL_HA, 33209467b48Spatrick 33309467b48Spatrick /// G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec 33409467b48Spatrick /// TLS model, produces a LD instruction with base register G8RReg 33509467b48Spatrick /// and offset sym\@got\@tprel\@l. This completes the addition that 33609467b48Spatrick /// finds the offset of "sym" relative to the thread pointer. 33709467b48Spatrick LD_GOT_TPREL_L, 33809467b48Spatrick 33909467b48Spatrick /// G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS 34009467b48Spatrick /// model, produces an ADD instruction that adds the contents of 34109467b48Spatrick /// G8RReg to the thread pointer. Symbol contains a relocation 34209467b48Spatrick /// sym\@tls which is to be replaced by the thread pointer and 34309467b48Spatrick /// identifies to the linker that the instruction is part of a 34409467b48Spatrick /// TLS sequence. 34509467b48Spatrick ADD_TLS, 34609467b48Spatrick 34709467b48Spatrick /// G8RC = ADDIS_TLSGD_HA %x2, Symbol - For the general-dynamic TLS 34809467b48Spatrick /// model, produces an ADDIS8 instruction that adds the GOT base 34909467b48Spatrick /// register to sym\@got\@tlsgd\@ha. 35009467b48Spatrick ADDIS_TLSGD_HA, 35109467b48Spatrick 35209467b48Spatrick /// %x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS 35309467b48Spatrick /// model, produces an ADDI8 instruction that adds G8RReg to 35409467b48Spatrick /// sym\@got\@tlsgd\@l and stores the result in X3. Hidden by 35509467b48Spatrick /// ADDIS_TLSGD_L_ADDR until after register assignment. 35609467b48Spatrick ADDI_TLSGD_L, 35709467b48Spatrick 35809467b48Spatrick /// %x3 = GET_TLS_ADDR %x3, Symbol - For the general-dynamic TLS 35909467b48Spatrick /// model, produces a call to __tls_get_addr(sym\@tlsgd). Hidden by 36009467b48Spatrick /// ADDIS_TLSGD_L_ADDR until after register assignment. 36109467b48Spatrick GET_TLS_ADDR, 36209467b48Spatrick 36309467b48Spatrick /// G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that 36409467b48Spatrick /// combines ADDI_TLSGD_L and GET_TLS_ADDR until expansion following 36509467b48Spatrick /// register assignment. 36609467b48Spatrick ADDI_TLSGD_L_ADDR, 36709467b48Spatrick 36873471bf0Spatrick /// GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY 36973471bf0Spatrick /// G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY 37073471bf0Spatrick /// Op that combines two register copies of TOC entries 37173471bf0Spatrick /// (region handle into R3 and variable offset into R4) followed by a 37273471bf0Spatrick /// GET_TLS_ADDR node which will be expanded to a call to __get_tls_addr. 37373471bf0Spatrick /// This node is used in 64-bit mode as well (in which case the result is 37473471bf0Spatrick /// G8RC and inputs are X3/X4). 37573471bf0Spatrick TLSGD_AIX, 37673471bf0Spatrick 37709467b48Spatrick /// G8RC = ADDIS_TLSLD_HA %x2, Symbol - For the local-dynamic TLS 37809467b48Spatrick /// model, produces an ADDIS8 instruction that adds the GOT base 37909467b48Spatrick /// register to sym\@got\@tlsld\@ha. 38009467b48Spatrick ADDIS_TLSLD_HA, 38109467b48Spatrick 38209467b48Spatrick /// %x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS 38309467b48Spatrick /// model, produces an ADDI8 instruction that adds G8RReg to 38409467b48Spatrick /// sym\@got\@tlsld\@l and stores the result in X3. Hidden by 38509467b48Spatrick /// ADDIS_TLSLD_L_ADDR until after register assignment. 38609467b48Spatrick ADDI_TLSLD_L, 38709467b48Spatrick 38809467b48Spatrick /// %x3 = GET_TLSLD_ADDR %x3, Symbol - For the local-dynamic TLS 38909467b48Spatrick /// model, produces a call to __tls_get_addr(sym\@tlsld). Hidden by 39009467b48Spatrick /// ADDIS_TLSLD_L_ADDR until after register assignment. 39109467b48Spatrick GET_TLSLD_ADDR, 39209467b48Spatrick 39309467b48Spatrick /// G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that 39409467b48Spatrick /// combines ADDI_TLSLD_L and GET_TLSLD_ADDR until expansion 39509467b48Spatrick /// following register assignment. 39609467b48Spatrick ADDI_TLSLD_L_ADDR, 39709467b48Spatrick 39809467b48Spatrick /// G8RC = ADDIS_DTPREL_HA %x3, Symbol - For the local-dynamic TLS 39909467b48Spatrick /// model, produces an ADDIS8 instruction that adds X3 to 40009467b48Spatrick /// sym\@dtprel\@ha. 40109467b48Spatrick ADDIS_DTPREL_HA, 40209467b48Spatrick 40309467b48Spatrick /// G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS 40409467b48Spatrick /// model, produces an ADDI8 instruction that adds G8RReg to 40509467b48Spatrick /// sym\@got\@dtprel\@l. 40609467b48Spatrick ADDI_DTPREL_L, 40709467b48Spatrick 40873471bf0Spatrick /// G8RC = PADDI_DTPREL %x3, Symbol - For the pc-rel based local-dynamic TLS 40973471bf0Spatrick /// model, produces a PADDI8 instruction that adds X3 to sym\@dtprel. 41073471bf0Spatrick PADDI_DTPREL, 41173471bf0Spatrick 41209467b48Spatrick /// VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded 41309467b48Spatrick /// during instruction selection to optimize a BUILD_VECTOR into 41409467b48Spatrick /// operations on splats. This is necessary to avoid losing these 41509467b48Spatrick /// optimizations due to constant folding. 41609467b48Spatrick VADD_SPLAT, 41709467b48Spatrick 41809467b48Spatrick /// CHAIN = SC CHAIN, Imm128 - System call. The 7-bit unsigned 41909467b48Spatrick /// operand identifies the operating system entry point. 42009467b48Spatrick SC, 42109467b48Spatrick 42209467b48Spatrick /// CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer. 42309467b48Spatrick CLRBHRB, 42409467b48Spatrick 42509467b48Spatrick /// GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch 42609467b48Spatrick /// history rolling buffer entry. 42709467b48Spatrick MFBHRBE, 42809467b48Spatrick 42909467b48Spatrick /// CHAIN = RFEBB CHAIN, State - Return from event-based branch. 43009467b48Spatrick RFEBB, 43109467b48Spatrick 43209467b48Spatrick /// VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little 43309467b48Spatrick /// endian. Maps to an xxswapd instruction that corrects an lxvd2x 43409467b48Spatrick /// or stxvd2x instruction. The chain is necessary because the 43509467b48Spatrick /// sequence replaces a load and needs to provide the same number 43609467b48Spatrick /// of outputs. 43709467b48Spatrick XXSWAPD, 43809467b48Spatrick 43909467b48Spatrick /// An SDNode for swaps that are not associated with any loads/stores 44009467b48Spatrick /// and thereby have no chain. 44109467b48Spatrick SWAP_NO_CHAIN, 44209467b48Spatrick 44309467b48Spatrick /// An SDNode for Power9 vector absolute value difference. 44409467b48Spatrick /// operand #0 vector 44509467b48Spatrick /// operand #1 vector 44609467b48Spatrick /// operand #2 constant i32 0 or 1, to indicate whether needs to patch 44709467b48Spatrick /// the most significant bit for signed i32 44809467b48Spatrick /// 44909467b48Spatrick /// Power9 VABSD* instructions are designed to support unsigned integer 45009467b48Spatrick /// vectors (byte/halfword/word), if we want to make use of them for signed 45109467b48Spatrick /// integer vectors, we have to flip their sign bits first. To flip sign bit 45209467b48Spatrick /// for byte/halfword integer vector would become inefficient, but for word 45309467b48Spatrick /// integer vector, we can leverage XVNEGSP to make it efficiently. eg: 45409467b48Spatrick /// abs(sub(a,b)) => VABSDUW(a+0x80000000, b+0x80000000) 45509467b48Spatrick /// => VABSDUW((XVNEGSP a), (XVNEGSP b)) 45609467b48Spatrick VABSD, 45709467b48Spatrick 45809467b48Spatrick /// FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or 45909467b48Spatrick /// lower (IDX=1) half of v4f32 to v2f64. 46009467b48Spatrick FP_EXTEND_HALF, 46109467b48Spatrick 462097a140dSpatrick /// MAT_PCREL_ADDR = Materialize a PC Relative address. This can be done 463097a140dSpatrick /// either through an add like PADDI or through a PC Relative load like 464097a140dSpatrick /// PLD. 465097a140dSpatrick MAT_PCREL_ADDR, 466097a140dSpatrick 46773471bf0Spatrick /// TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for 46873471bf0Spatrick /// TLS global address when using dynamic access models. This can be done 46973471bf0Spatrick /// through an add like PADDI. 47073471bf0Spatrick TLS_DYNAMIC_MAT_PCREL_ADDR, 47173471bf0Spatrick 47273471bf0Spatrick /// TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address 47373471bf0Spatrick /// when using local exec access models, and when prefixed instructions are 47473471bf0Spatrick /// available. This is used with ADD_TLS to produce an add like PADDI. 47573471bf0Spatrick TLS_LOCAL_EXEC_MAT_ADDR, 47673471bf0Spatrick 47773471bf0Spatrick /// ACC_BUILD = Build an accumulator register from 4 VSX registers. 47873471bf0Spatrick ACC_BUILD, 47973471bf0Spatrick 48073471bf0Spatrick /// PAIR_BUILD = Build a vector pair register from 2 VSX registers. 48173471bf0Spatrick PAIR_BUILD, 48273471bf0Spatrick 48373471bf0Spatrick /// EXTRACT_VSX_REG = Extract one of the underlying vsx registers of 48473471bf0Spatrick /// an accumulator or pair register. This node is needed because 48573471bf0Spatrick /// EXTRACT_SUBVECTOR expects the input and output vectors to have the same 48673471bf0Spatrick /// element type. 48773471bf0Spatrick EXTRACT_VSX_REG, 48873471bf0Spatrick 48973471bf0Spatrick /// XXMFACC = This corresponds to the xxmfacc instruction. 49073471bf0Spatrick XXMFACC, 49173471bf0Spatrick 49273471bf0Spatrick // Constrained conversion from floating point to int 49373471bf0Spatrick STRICT_FCTIDZ = ISD::FIRST_TARGET_STRICTFP_OPCODE, 49473471bf0Spatrick STRICT_FCTIWZ, 49573471bf0Spatrick STRICT_FCTIDUZ, 49673471bf0Spatrick STRICT_FCTIWUZ, 49773471bf0Spatrick 49873471bf0Spatrick /// Constrained integer-to-floating-point conversion instructions. 49973471bf0Spatrick STRICT_FCFID, 50073471bf0Spatrick STRICT_FCFIDU, 50173471bf0Spatrick STRICT_FCFIDS, 50273471bf0Spatrick STRICT_FCFIDUS, 50373471bf0Spatrick 50473471bf0Spatrick /// Constrained floating point add in round-to-zero mode. 50573471bf0Spatrick STRICT_FADDRTZ, 50673471bf0Spatrick 507*d415bd75Srobert // NOTE: The nodes below may require PC-Rel specific patterns if the 508*d415bd75Srobert // address could be PC-Relative. When adding new nodes below, consider 509*d415bd75Srobert // whether or not the address can be PC-Relative and add the corresponding 510*d415bd75Srobert // PC-relative patterns and tests. 511*d415bd75Srobert 51209467b48Spatrick /// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a 51309467b48Spatrick /// byte-swapping store instruction. It byte-swaps the low "Type" bits of 51409467b48Spatrick /// the GPRC input, then stores it through Ptr. Type can be either i16 or 51509467b48Spatrick /// i32. 51609467b48Spatrick STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE, 51709467b48Spatrick 51809467b48Spatrick /// GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a 51909467b48Spatrick /// byte-swapping load instruction. It loads "Type" bits, byte swaps it, 52009467b48Spatrick /// then puts it in the bottom bits of the GPRC. TYPE can be either i16 52109467b48Spatrick /// or i32. 52209467b48Spatrick LBRX, 52309467b48Spatrick 52409467b48Spatrick /// STFIWX - The STFIWX instruction. The first operand is an input token 52509467b48Spatrick /// chain, then an f64 value to store, then an address to store it to. 52609467b48Spatrick STFIWX, 52709467b48Spatrick 52809467b48Spatrick /// GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point 52909467b48Spatrick /// load which sign-extends from a 32-bit integer value into the 53009467b48Spatrick /// destination 64-bit register. 53109467b48Spatrick LFIWAX, 53209467b48Spatrick 53309467b48Spatrick /// GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point 53409467b48Spatrick /// load which zero-extends from a 32-bit integer value into the 53509467b48Spatrick /// destination 64-bit register. 53609467b48Spatrick LFIWZX, 53709467b48Spatrick 53809467b48Spatrick /// GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an 53909467b48Spatrick /// integer smaller than 64 bits into a VSR. The integer is zero-extended. 54009467b48Spatrick /// This can be used for converting loaded integers to floating point. 54109467b48Spatrick LXSIZX, 54209467b48Spatrick 54309467b48Spatrick /// STXSIX - The STXSI[bh]X instruction. The first operand is an input 54409467b48Spatrick /// chain, then an f64 value to store, then an address to store it to, 54509467b48Spatrick /// followed by a byte-width for the store. 54609467b48Spatrick STXSIX, 54709467b48Spatrick 54809467b48Spatrick /// VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian. 54909467b48Spatrick /// Maps directly to an lxvd2x instruction that will be followed by 55009467b48Spatrick /// an xxswapd. 55109467b48Spatrick LXVD2X, 55209467b48Spatrick 55373471bf0Spatrick /// LXVRZX - Load VSX Vector Rightmost and Zero Extend 55473471bf0Spatrick /// This node represents v1i128 BUILD_VECTOR of a zero extending load 55573471bf0Spatrick /// instruction from <byte, halfword, word, or doubleword> to i128. 55673471bf0Spatrick /// Allows utilization of the Load VSX Vector Rightmost Instructions. 55773471bf0Spatrick LXVRZX, 55873471bf0Spatrick 55909467b48Spatrick /// VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian. 56009467b48Spatrick /// Maps directly to one of lxvd2x/lxvw4x/lxvh8x/lxvb16x depending on 56109467b48Spatrick /// the vector type to load vector in big-endian element order. 56209467b48Spatrick LOAD_VEC_BE, 56309467b48Spatrick 56409467b48Spatrick /// VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a 56509467b48Spatrick /// v2f32 value into the lower half of a VSR register. 56609467b48Spatrick LD_VSX_LH, 56709467b48Spatrick 56809467b48Spatrick /// VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory 56909467b48Spatrick /// instructions such as LXVDSX, LXVWSX. 57009467b48Spatrick LD_SPLAT, 57109467b48Spatrick 572*d415bd75Srobert /// VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory 573*d415bd75Srobert /// that zero-extends. 574*d415bd75Srobert ZEXT_LD_SPLAT, 575*d415bd75Srobert 576*d415bd75Srobert /// VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory 577*d415bd75Srobert /// that sign-extends. 578*d415bd75Srobert SEXT_LD_SPLAT, 579*d415bd75Srobert 58009467b48Spatrick /// CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian. 58109467b48Spatrick /// Maps directly to an stxvd2x instruction that will be preceded by 58209467b48Spatrick /// an xxswapd. 58309467b48Spatrick STXVD2X, 58409467b48Spatrick 58509467b48Spatrick /// CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian. 58609467b48Spatrick /// Maps directly to one of stxvd2x/stxvw4x/stxvh8x/stxvb16x depending on 58709467b48Spatrick /// the vector type to store vector in big-endian element order. 58809467b48Spatrick STORE_VEC_BE, 58909467b48Spatrick 59009467b48Spatrick /// Store scalar integers from VSR. 59109467b48Spatrick ST_VSR_SCAL_INT, 59209467b48Spatrick 59309467b48Spatrick /// ATOMIC_CMP_SWAP - the exact same as the target-independent nodes 59409467b48Spatrick /// except they ensure that the compare input is zero-extended for 59509467b48Spatrick /// sub-word versions because the atomic loads zero-extend. 59609467b48Spatrick ATOMIC_CMP_SWAP_8, 59709467b48Spatrick ATOMIC_CMP_SWAP_16, 59809467b48Spatrick 599*d415bd75Srobert /// CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr 600*d415bd75Srobert /// The store conditional instruction ST[BHWD]ARX that produces a glue 601*d415bd75Srobert /// result to attach it to a conditional branch. 602*d415bd75Srobert STORE_COND, 603*d415bd75Srobert 60409467b48Spatrick /// GPRC = TOC_ENTRY GA, TOC 60509467b48Spatrick /// Loads the entry for GA from the TOC, where the TOC base is given by 60609467b48Spatrick /// the last operand. 60709467b48Spatrick TOC_ENTRY 60809467b48Spatrick }; 60909467b48Spatrick 61009467b48Spatrick } // end namespace PPCISD 61109467b48Spatrick 61209467b48Spatrick /// Define some predicates that are used for node matching. 61309467b48Spatrick namespace PPC { 61409467b48Spatrick 61509467b48Spatrick /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a 61609467b48Spatrick /// VPKUHUM instruction. 61709467b48Spatrick bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, 61809467b48Spatrick SelectionDAG &DAG); 61909467b48Spatrick 62009467b48Spatrick /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a 62109467b48Spatrick /// VPKUWUM instruction. 62209467b48Spatrick bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, 62309467b48Spatrick SelectionDAG &DAG); 62409467b48Spatrick 62509467b48Spatrick /// isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a 62609467b48Spatrick /// VPKUDUM instruction. 62709467b48Spatrick bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, 62809467b48Spatrick SelectionDAG &DAG); 62909467b48Spatrick 63009467b48Spatrick /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for 63109467b48Spatrick /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes). 63209467b48Spatrick bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, 63309467b48Spatrick unsigned ShuffleKind, SelectionDAG &DAG); 63409467b48Spatrick 63509467b48Spatrick /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for 63609467b48Spatrick /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes). 63709467b48Spatrick bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, 63809467b48Spatrick unsigned ShuffleKind, SelectionDAG &DAG); 63909467b48Spatrick 64009467b48Spatrick /// isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for 64109467b48Spatrick /// a VMRGEW or VMRGOW instruction 64209467b48Spatrick bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, 64309467b48Spatrick unsigned ShuffleKind, SelectionDAG &DAG); 64409467b48Spatrick /// isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable 64509467b48Spatrick /// for a XXSLDWI instruction. 64609467b48Spatrick bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, 64709467b48Spatrick bool &Swap, bool IsLE); 64809467b48Spatrick 64909467b48Spatrick /// isXXBRHShuffleMask - Return true if this is a shuffle mask suitable 65009467b48Spatrick /// for a XXBRH instruction. 65109467b48Spatrick bool isXXBRHShuffleMask(ShuffleVectorSDNode *N); 65209467b48Spatrick 65309467b48Spatrick /// isXXBRWShuffleMask - Return true if this is a shuffle mask suitable 65409467b48Spatrick /// for a XXBRW instruction. 65509467b48Spatrick bool isXXBRWShuffleMask(ShuffleVectorSDNode *N); 65609467b48Spatrick 65709467b48Spatrick /// isXXBRDShuffleMask - Return true if this is a shuffle mask suitable 65809467b48Spatrick /// for a XXBRD instruction. 65909467b48Spatrick bool isXXBRDShuffleMask(ShuffleVectorSDNode *N); 66009467b48Spatrick 66109467b48Spatrick /// isXXBRQShuffleMask - Return true if this is a shuffle mask suitable 66209467b48Spatrick /// for a XXBRQ instruction. 66309467b48Spatrick bool isXXBRQShuffleMask(ShuffleVectorSDNode *N); 66409467b48Spatrick 66509467b48Spatrick /// isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable 66609467b48Spatrick /// for a XXPERMDI instruction. 66709467b48Spatrick bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, 66809467b48Spatrick bool &Swap, bool IsLE); 66909467b48Spatrick 67009467b48Spatrick /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the 67109467b48Spatrick /// shift amount, otherwise return -1. 67209467b48Spatrick int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, 67309467b48Spatrick SelectionDAG &DAG); 67409467b48Spatrick 67509467b48Spatrick /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand 67609467b48Spatrick /// specifies a splat of a single element that is suitable for input to 67709467b48Spatrick /// VSPLTB/VSPLTH/VSPLTW. 67809467b48Spatrick bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize); 67909467b48Spatrick 68009467b48Spatrick /// isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by 68109467b48Spatrick /// the XXINSERTW instruction introduced in ISA 3.0. This is essentially any 68209467b48Spatrick /// shuffle of v4f32/v4i32 vectors that just inserts one element from one 68309467b48Spatrick /// vector into the other. This function will also set a couple of 68409467b48Spatrick /// output parameters for how much the source vector needs to be shifted and 68509467b48Spatrick /// what byte number needs to be specified for the instruction to put the 68609467b48Spatrick /// element in the desired location of the target vector. 68709467b48Spatrick bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, 68809467b48Spatrick unsigned &InsertAtByte, bool &Swap, bool IsLE); 68909467b48Spatrick 69009467b48Spatrick /// getSplatIdxForPPCMnemonics - Return the splat index as a value that is 69109467b48Spatrick /// appropriate for PPC mnemonics (which have a big endian bias - namely 69209467b48Spatrick /// elements are counted from the left of the vector register). 69309467b48Spatrick unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, 69409467b48Spatrick SelectionDAG &DAG); 69509467b48Spatrick 69609467b48Spatrick /// get_VSPLTI_elt - If this is a build_vector of constants which can be 69709467b48Spatrick /// formed by using a vspltis[bhw] instruction of the specified element 69809467b48Spatrick /// size, return the constant being splatted. The ByteSize field indicates 69909467b48Spatrick /// the number of bytes of each element [124] -> [bhw]. 70009467b48Spatrick SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG); 70109467b48Spatrick 70273471bf0Spatrick // Flags for computing the optimal addressing mode for loads and stores. 70373471bf0Spatrick enum MemOpFlags { 70473471bf0Spatrick MOF_None = 0, 70509467b48Spatrick 70673471bf0Spatrick // Extension mode for integer loads. 70773471bf0Spatrick MOF_SExt = 1, 70873471bf0Spatrick MOF_ZExt = 1 << 1, 70973471bf0Spatrick MOF_NoExt = 1 << 2, 71073471bf0Spatrick 71173471bf0Spatrick // Address computation flags. 71273471bf0Spatrick MOF_NotAddNorCst = 1 << 5, // Not const. or sum of ptr and scalar. 71373471bf0Spatrick MOF_RPlusSImm16 = 1 << 6, // Reg plus signed 16-bit constant. 71473471bf0Spatrick MOF_RPlusLo = 1 << 7, // Reg plus signed 16-bit relocation 71573471bf0Spatrick MOF_RPlusSImm16Mult4 = 1 << 8, // Reg plus 16-bit signed multiple of 4. 71673471bf0Spatrick MOF_RPlusSImm16Mult16 = 1 << 9, // Reg plus 16-bit signed multiple of 16. 71773471bf0Spatrick MOF_RPlusSImm34 = 1 << 10, // Reg plus 34-bit signed constant. 71873471bf0Spatrick MOF_RPlusR = 1 << 11, // Sum of two variables. 71973471bf0Spatrick MOF_PCRel = 1 << 12, // PC-Relative relocation. 72073471bf0Spatrick MOF_AddrIsSImm32 = 1 << 13, // A simple 32-bit constant. 72173471bf0Spatrick 72273471bf0Spatrick // The in-memory type. 72373471bf0Spatrick MOF_SubWordInt = 1 << 15, 72473471bf0Spatrick MOF_WordInt = 1 << 16, 72573471bf0Spatrick MOF_DoubleWordInt = 1 << 17, 72673471bf0Spatrick MOF_ScalarFloat = 1 << 18, // Scalar single or double precision. 72773471bf0Spatrick MOF_Vector = 1 << 19, // Vector types and quad precision scalars. 72873471bf0Spatrick MOF_Vector256 = 1 << 20, 72973471bf0Spatrick 73073471bf0Spatrick // Subtarget features. 73173471bf0Spatrick MOF_SubtargetBeforeP9 = 1 << 22, 73273471bf0Spatrick MOF_SubtargetP9 = 1 << 23, 73373471bf0Spatrick MOF_SubtargetP10 = 1 << 24, 73473471bf0Spatrick MOF_SubtargetSPE = 1 << 25 73573471bf0Spatrick }; 73673471bf0Spatrick 73773471bf0Spatrick // The addressing modes for loads and stores. 73873471bf0Spatrick enum AddrMode { 73973471bf0Spatrick AM_None, 74073471bf0Spatrick AM_DForm, 74173471bf0Spatrick AM_DSForm, 74273471bf0Spatrick AM_DQForm, 743*d415bd75Srobert AM_PrefixDForm, 74473471bf0Spatrick AM_XForm, 745*d415bd75Srobert AM_PCRel 74673471bf0Spatrick }; 74709467b48Spatrick } // end namespace PPC 74809467b48Spatrick 74909467b48Spatrick class PPCTargetLowering : public TargetLowering { 75009467b48Spatrick const PPCSubtarget &Subtarget; 75109467b48Spatrick 75209467b48Spatrick public: 75309467b48Spatrick explicit PPCTargetLowering(const PPCTargetMachine &TM, 75409467b48Spatrick const PPCSubtarget &STI); 75509467b48Spatrick 75609467b48Spatrick /// getTargetNodeName() - This method returns the name of a target specific 75709467b48Spatrick /// DAG node. 75809467b48Spatrick const char *getTargetNodeName(unsigned Opcode) const override; 75909467b48Spatrick isSelectSupported(SelectSupportKind Kind)76009467b48Spatrick bool isSelectSupported(SelectSupportKind Kind) const override { 76109467b48Spatrick // PowerPC does not support scalar condition selects on vectors. 76209467b48Spatrick return (Kind != SelectSupportKind::ScalarCondVectorVal); 76309467b48Spatrick } 76409467b48Spatrick 76509467b48Spatrick /// getPreferredVectorAction - The code we generate when vector types are 76609467b48Spatrick /// legalized by promoting the integer element type is often much worse 76709467b48Spatrick /// than code we generate if we widen the type for applicable vector types. 76809467b48Spatrick /// The issue with promoting is that the vector is scalaraized, individual 76909467b48Spatrick /// elements promoted and then the vector is rebuilt. So say we load a pair 77009467b48Spatrick /// of v4i8's and shuffle them. This will turn into a mess of 8 extending 77109467b48Spatrick /// loads, moves back into VSR's (or memory ops if we don't have moves) and 77209467b48Spatrick /// then the VPERM for the shuffle. All in all a very slow sequence. getPreferredVectorAction(MVT VT)77309467b48Spatrick TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) 77409467b48Spatrick const override { 775*d415bd75Srobert // Default handling for scalable and single-element vectors. 776*d415bd75Srobert if (VT.isScalableVector() || VT.getVectorNumElements() == 1) 777*d415bd75Srobert return TargetLoweringBase::getPreferredVectorAction(VT); 778*d415bd75Srobert 779*d415bd75Srobert // Split and promote vNi1 vectors so we don't produce v256i1/v512i1 780*d415bd75Srobert // types as those are only for MMA instructions. 781*d415bd75Srobert if (VT.getScalarSizeInBits() == 1 && VT.getSizeInBits() > 16) 782*d415bd75Srobert return TypeSplitVector; 783*d415bd75Srobert if (VT.getScalarSizeInBits() == 1) 784*d415bd75Srobert return TypePromoteInteger; 785*d415bd75Srobert 786*d415bd75Srobert // Widen vectors that have reasonably sized elements. 787*d415bd75Srobert if (VT.getScalarSizeInBits() % 8 == 0) 78809467b48Spatrick return TypeWidenVector; 78909467b48Spatrick return TargetLoweringBase::getPreferredVectorAction(VT); 79009467b48Spatrick } 79109467b48Spatrick 79209467b48Spatrick bool useSoftFloat() const override; 79309467b48Spatrick 79409467b48Spatrick bool hasSPE() const; 79509467b48Spatrick getScalarShiftAmountTy(const DataLayout &,EVT)79609467b48Spatrick MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 79709467b48Spatrick return MVT::i32; 79809467b48Spatrick } 79909467b48Spatrick isCheapToSpeculateCttz(Type * Ty)800*d415bd75Srobert bool isCheapToSpeculateCttz(Type *Ty) const override { 80109467b48Spatrick return true; 80209467b48Spatrick } 80309467b48Spatrick isCheapToSpeculateCtlz(Type * Ty)804*d415bd75Srobert bool isCheapToSpeculateCtlz(Type *Ty) const override { 80509467b48Spatrick return true; 80609467b48Spatrick } 80709467b48Spatrick isCtlzFast()80809467b48Spatrick bool isCtlzFast() const override { 80909467b48Spatrick return true; 81009467b48Spatrick } 81109467b48Spatrick isEqualityCmpFoldedWithSignedCmp()81209467b48Spatrick bool isEqualityCmpFoldedWithSignedCmp() const override { 81309467b48Spatrick return false; 81409467b48Spatrick } 81509467b48Spatrick hasAndNotCompare(SDValue)81609467b48Spatrick bool hasAndNotCompare(SDValue) const override { 81709467b48Spatrick return true; 81809467b48Spatrick } 81909467b48Spatrick 82009467b48Spatrick bool preferIncOfAddToSubOfNot(EVT VT) const override; 82109467b48Spatrick convertSetCCLogicToBitwiseLogic(EVT VT)82209467b48Spatrick bool convertSetCCLogicToBitwiseLogic(EVT VT) const override { 82309467b48Spatrick return VT.isScalarInteger(); 82409467b48Spatrick } 82509467b48Spatrick 826097a140dSpatrick SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, 827097a140dSpatrick bool OptForSize, NegatibleCost &Cost, 828097a140dSpatrick unsigned Depth = 0) const override; 82909467b48Spatrick 83009467b48Spatrick /// getSetCCResultType - Return the ISD::SETCC ValueType 83109467b48Spatrick EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 83209467b48Spatrick EVT VT) const override; 83309467b48Spatrick 83473471bf0Spatrick /// Return true if target always benefits from combining into FMA for a 83509467b48Spatrick /// given value type. This must typically return false on targets where FMA 83609467b48Spatrick /// takes more cycles to execute than FADD. 83709467b48Spatrick bool enableAggressiveFMAFusion(EVT VT) const override; 83809467b48Spatrick 83909467b48Spatrick /// getPreIndexedAddressParts - returns true by value, base pointer and 84009467b48Spatrick /// offset pointer and addressing mode by reference if the node's address 84109467b48Spatrick /// can be legally represented as pre-indexed load / store address. 84209467b48Spatrick bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, 84309467b48Spatrick SDValue &Offset, 84409467b48Spatrick ISD::MemIndexedMode &AM, 84509467b48Spatrick SelectionDAG &DAG) const override; 84609467b48Spatrick 84709467b48Spatrick /// SelectAddressEVXRegReg - Given the specified addressed, check to see if 84809467b48Spatrick /// it can be more efficiently represented as [r+imm]. 84909467b48Spatrick bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, 85009467b48Spatrick SelectionDAG &DAG) const; 85109467b48Spatrick 85209467b48Spatrick /// SelectAddressRegReg - Given the specified addressed, check to see if it 85309467b48Spatrick /// can be more efficiently represented as [r+imm]. If \p EncodingAlignment 85409467b48Spatrick /// is non-zero, only accept displacement which is not suitable for [r+imm]. 85509467b48Spatrick /// Returns false if it can be represented by [r+imm], which are preferred. 85609467b48Spatrick bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, 85709467b48Spatrick SelectionDAG &DAG, 858*d415bd75Srobert MaybeAlign EncodingAlignment = std::nullopt) const; 85909467b48Spatrick 86009467b48Spatrick /// SelectAddressRegImm - Returns true if the address N can be represented 86109467b48Spatrick /// by a base register plus a signed 16-bit displacement [r+imm], and if it 86209467b48Spatrick /// is not better represented as reg+reg. If \p EncodingAlignment is 86309467b48Spatrick /// non-zero, only accept displacements suitable for instruction encoding 86409467b48Spatrick /// requirement, i.e. multiples of 4 for DS form. 86509467b48Spatrick bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, 86609467b48Spatrick SelectionDAG &DAG, 867097a140dSpatrick MaybeAlign EncodingAlignment) const; 86873471bf0Spatrick bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, 86973471bf0Spatrick SelectionDAG &DAG) const; 87009467b48Spatrick 87109467b48Spatrick /// SelectAddressRegRegOnly - Given the specified addressed, force it to be 87209467b48Spatrick /// represented as an indexed [r+r] operation. 87309467b48Spatrick bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, 87409467b48Spatrick SelectionDAG &DAG) const; 87509467b48Spatrick 876097a140dSpatrick /// SelectAddressPCRel - Represent the specified address as pc relative to 877097a140dSpatrick /// be represented as [pc+imm] 878097a140dSpatrick bool SelectAddressPCRel(SDValue N, SDValue &Base) const; 879097a140dSpatrick 88009467b48Spatrick Sched::Preference getSchedulingPreference(SDNode *N) const override; 88109467b48Spatrick 88209467b48Spatrick /// LowerOperation - Provide custom lowering hooks for some operations. 88309467b48Spatrick /// 88409467b48Spatrick SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 88509467b48Spatrick 88609467b48Spatrick /// ReplaceNodeResults - Replace the results of node with an illegal result 88709467b48Spatrick /// type with new values built out of custom code. 88809467b48Spatrick /// 88909467b48Spatrick void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, 89009467b48Spatrick SelectionDAG &DAG) const override; 89109467b48Spatrick 89209467b48Spatrick SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const; 89309467b48Spatrick SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const; 89409467b48Spatrick 89509467b48Spatrick SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 89609467b48Spatrick 89709467b48Spatrick SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, 89809467b48Spatrick SmallVectorImpl<SDNode *> &Created) const override; 89909467b48Spatrick 90009467b48Spatrick Register getRegisterByName(const char* RegName, LLT VT, 90109467b48Spatrick const MachineFunction &MF) const override; 90209467b48Spatrick 90309467b48Spatrick void computeKnownBitsForTargetNode(const SDValue Op, 90409467b48Spatrick KnownBits &Known, 90509467b48Spatrick const APInt &DemandedElts, 90609467b48Spatrick const SelectionDAG &DAG, 90709467b48Spatrick unsigned Depth = 0) const override; 90809467b48Spatrick 90909467b48Spatrick Align getPrefLoopAlignment(MachineLoop *ML) const override; 91009467b48Spatrick shouldInsertFencesForAtomic(const Instruction * I)91109467b48Spatrick bool shouldInsertFencesForAtomic(const Instruction *I) const override { 91209467b48Spatrick return true; 91309467b48Spatrick } 91409467b48Spatrick 91573471bf0Spatrick Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 91609467b48Spatrick AtomicOrdering Ord) const override; 91773471bf0Spatrick Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 91873471bf0Spatrick AtomicOrdering Ord) const override; 91973471bf0Spatrick 920*d415bd75Srobert bool shouldInlineQuadwordAtomics() const; 921*d415bd75Srobert 92273471bf0Spatrick TargetLowering::AtomicExpansionKind 92373471bf0Spatrick shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 92473471bf0Spatrick 92573471bf0Spatrick TargetLowering::AtomicExpansionKind 92673471bf0Spatrick shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override; 92773471bf0Spatrick 92873471bf0Spatrick Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, 92973471bf0Spatrick AtomicRMWInst *AI, Value *AlignedAddr, 93073471bf0Spatrick Value *Incr, Value *Mask, 93173471bf0Spatrick Value *ShiftAmt, 93273471bf0Spatrick AtomicOrdering Ord) const override; 93373471bf0Spatrick Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, 93473471bf0Spatrick AtomicCmpXchgInst *CI, 93573471bf0Spatrick Value *AlignedAddr, Value *CmpVal, 93673471bf0Spatrick Value *NewVal, Value *Mask, 93709467b48Spatrick AtomicOrdering Ord) const override; 93809467b48Spatrick 93909467b48Spatrick MachineBasicBlock * 94009467b48Spatrick EmitInstrWithCustomInserter(MachineInstr &MI, 94109467b48Spatrick MachineBasicBlock *MBB) const override; 94209467b48Spatrick MachineBasicBlock *EmitAtomicBinary(MachineInstr &MI, 94309467b48Spatrick MachineBasicBlock *MBB, 94409467b48Spatrick unsigned AtomicSize, 94509467b48Spatrick unsigned BinOpcode, 94609467b48Spatrick unsigned CmpOpcode = 0, 94709467b48Spatrick unsigned CmpPred = 0) const; 94809467b48Spatrick MachineBasicBlock *EmitPartwordAtomicBinary(MachineInstr &MI, 94909467b48Spatrick MachineBasicBlock *MBB, 95009467b48Spatrick bool is8bit, 95109467b48Spatrick unsigned Opcode, 95209467b48Spatrick unsigned CmpOpcode = 0, 95309467b48Spatrick unsigned CmpPred = 0) const; 95409467b48Spatrick 95509467b48Spatrick MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 95609467b48Spatrick MachineBasicBlock *MBB) const; 95709467b48Spatrick 95809467b48Spatrick MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 95909467b48Spatrick MachineBasicBlock *MBB) const; 96009467b48Spatrick 961097a140dSpatrick MachineBasicBlock *emitProbedAlloca(MachineInstr &MI, 962097a140dSpatrick MachineBasicBlock *MBB) const; 963097a140dSpatrick 964*d415bd75Srobert bool hasInlineStackProbe(const MachineFunction &MF) const override; 965097a140dSpatrick 966*d415bd75Srobert unsigned getStackProbeSize(const MachineFunction &MF) const; 967097a140dSpatrick 96809467b48Spatrick ConstraintType getConstraintType(StringRef Constraint) const override; 96909467b48Spatrick 97009467b48Spatrick /// Examine constraint string and operand type and determine a weight value. 97109467b48Spatrick /// The operand object must already have been set up with the operand type. 97209467b48Spatrick ConstraintWeight getSingleConstraintMatchWeight( 97309467b48Spatrick AsmOperandInfo &info, const char *constraint) const override; 97409467b48Spatrick 97509467b48Spatrick std::pair<unsigned, const TargetRegisterClass *> 97609467b48Spatrick getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 97709467b48Spatrick StringRef Constraint, MVT VT) const override; 97809467b48Spatrick 97909467b48Spatrick /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate 98009467b48Spatrick /// function arguments in the caller parameter area. This is the actual 98109467b48Spatrick /// alignment, not its logarithm. 982*d415bd75Srobert uint64_t getByValTypeAlignment(Type *Ty, 98309467b48Spatrick const DataLayout &DL) const override; 98409467b48Spatrick 98509467b48Spatrick /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops 98609467b48Spatrick /// vector. If it is invalid, don't add anything to Ops. 98709467b48Spatrick void LowerAsmOperandForConstraint(SDValue Op, 98809467b48Spatrick std::string &Constraint, 98909467b48Spatrick std::vector<SDValue> &Ops, 99009467b48Spatrick SelectionDAG &DAG) const override; 99109467b48Spatrick 99209467b48Spatrick unsigned getInlineAsmMemConstraint(StringRef ConstraintCode)99309467b48Spatrick getInlineAsmMemConstraint(StringRef ConstraintCode) const override { 99409467b48Spatrick if (ConstraintCode == "es") 99509467b48Spatrick return InlineAsm::Constraint_es; 99609467b48Spatrick else if (ConstraintCode == "Q") 99709467b48Spatrick return InlineAsm::Constraint_Q; 99809467b48Spatrick else if (ConstraintCode == "Z") 99909467b48Spatrick return InlineAsm::Constraint_Z; 100009467b48Spatrick else if (ConstraintCode == "Zy") 100109467b48Spatrick return InlineAsm::Constraint_Zy; 100209467b48Spatrick return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); 100309467b48Spatrick } 100409467b48Spatrick 1005*d415bd75Srobert void CollectTargetIntrinsicOperands(const CallInst &I, 1006*d415bd75Srobert SmallVectorImpl<SDValue> &Ops, 1007*d415bd75Srobert SelectionDAG &DAG) const override; 1008*d415bd75Srobert 100909467b48Spatrick /// isLegalAddressingMode - Return true if the addressing mode represented 101009467b48Spatrick /// by AM is legal for this target, for a load/store of the specified type. 101109467b48Spatrick bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, 101209467b48Spatrick Type *Ty, unsigned AS, 101309467b48Spatrick Instruction *I = nullptr) const override; 101409467b48Spatrick 101509467b48Spatrick /// isLegalICmpImmediate - Return true if the specified immediate is legal 101609467b48Spatrick /// icmp immediate, that is the target has icmp instructions which can 101709467b48Spatrick /// compare a register against the immediate without having to materialize 101809467b48Spatrick /// the immediate into a register. 101909467b48Spatrick bool isLegalICmpImmediate(int64_t Imm) const override; 102009467b48Spatrick 102109467b48Spatrick /// isLegalAddImmediate - Return true if the specified immediate is legal 102209467b48Spatrick /// add immediate, that is the target has add instructions which can 102309467b48Spatrick /// add a register and the immediate without having to materialize 102409467b48Spatrick /// the immediate into a register. 102509467b48Spatrick bool isLegalAddImmediate(int64_t Imm) const override; 102609467b48Spatrick 102709467b48Spatrick /// isTruncateFree - Return true if it's free to truncate a value of 102809467b48Spatrick /// type Ty1 to type Ty2. e.g. On PPC it's free to truncate a i64 value in 102909467b48Spatrick /// register X1 to i32 by referencing its sub-register R1. 103009467b48Spatrick bool isTruncateFree(Type *Ty1, Type *Ty2) const override; 103109467b48Spatrick bool isTruncateFree(EVT VT1, EVT VT2) const override; 103209467b48Spatrick 103309467b48Spatrick bool isZExtFree(SDValue Val, EVT VT2) const override; 103409467b48Spatrick 103509467b48Spatrick bool isFPExtFree(EVT DestVT, EVT SrcVT) const override; 103609467b48Spatrick 103709467b48Spatrick /// Returns true if it is beneficial to convert a load of a constant 103809467b48Spatrick /// to just the constant itself. 103909467b48Spatrick bool shouldConvertConstantLoadToIntImm(const APInt &Imm, 104009467b48Spatrick Type *Ty) const override; 104109467b48Spatrick convertSelectOfConstantsToMath(EVT VT)104209467b48Spatrick bool convertSelectOfConstantsToMath(EVT VT) const override { 104309467b48Spatrick return true; 104409467b48Spatrick } 104509467b48Spatrick 104673471bf0Spatrick bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 104773471bf0Spatrick SDValue C) const override; 104873471bf0Spatrick isDesirableToTransformToIntegerOp(unsigned Opc,EVT VT)104909467b48Spatrick bool isDesirableToTransformToIntegerOp(unsigned Opc, 105009467b48Spatrick EVT VT) const override { 105109467b48Spatrick // Only handle float load/store pair because float(fpr) load/store 105209467b48Spatrick // instruction has more cycles than integer(gpr) load/store in PPC. 105309467b48Spatrick if (Opc != ISD::LOAD && Opc != ISD::STORE) 105409467b48Spatrick return false; 105509467b48Spatrick if (VT != MVT::f32 && VT != MVT::f64) 105609467b48Spatrick return false; 105709467b48Spatrick 105809467b48Spatrick return true; 105909467b48Spatrick } 106009467b48Spatrick 106109467b48Spatrick // Returns true if the address of the global is stored in TOC entry. 106209467b48Spatrick bool isAccessedAsGotIndirect(SDValue N) const; 106309467b48Spatrick 106409467b48Spatrick bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 106509467b48Spatrick 106609467b48Spatrick bool getTgtMemIntrinsic(IntrinsicInfo &Info, 106709467b48Spatrick const CallInst &I, 106809467b48Spatrick MachineFunction &MF, 106909467b48Spatrick unsigned Intrinsic) const override; 107009467b48Spatrick 107109467b48Spatrick /// It returns EVT::Other if the type should be determined using generic 107209467b48Spatrick /// target-independent logic. 1073097a140dSpatrick EVT getOptimalMemOpType(const MemOp &Op, 107409467b48Spatrick const AttributeList &FuncAttributes) const override; 107509467b48Spatrick 107609467b48Spatrick /// Is unaligned memory access allowed for the given type, and is it fast 107709467b48Spatrick /// relative to software emulation. 107809467b48Spatrick bool allowsMisalignedMemoryAccesses( 107973471bf0Spatrick EVT VT, unsigned AddrSpace, Align Alignment = Align(1), 108009467b48Spatrick MachineMemOperand::Flags Flags = MachineMemOperand::MONone, 1081*d415bd75Srobert unsigned *Fast = nullptr) const override; 108209467b48Spatrick 108309467b48Spatrick /// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster 108409467b48Spatrick /// than a pair of fmul and fadd instructions. fmuladd intrinsics will be 108509467b48Spatrick /// expanded to FMAs when this method returns true, otherwise fmuladd is 108609467b48Spatrick /// expanded to fmul + fadd. 108709467b48Spatrick bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, 108809467b48Spatrick EVT VT) const override; 108909467b48Spatrick 1090097a140dSpatrick bool isFMAFasterThanFMulAndFAdd(const Function &F, Type *Ty) const override; 1091097a140dSpatrick 1092097a140dSpatrick /// isProfitableToHoist - Check if it is profitable to hoist instruction 1093097a140dSpatrick /// \p I to its dominator block. 1094097a140dSpatrick /// For example, it is not profitable if \p I and it's only user can form a 1095097a140dSpatrick /// FMA instruction, because Powerpc prefers FMADD. 1096097a140dSpatrick bool isProfitableToHoist(Instruction *I) const override; 1097097a140dSpatrick 109809467b48Spatrick const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override; 109909467b48Spatrick 110009467b48Spatrick // Should we expand the build vector with shuffles? 110109467b48Spatrick bool 110209467b48Spatrick shouldExpandBuildVectorWithShuffles(EVT VT, 110309467b48Spatrick unsigned DefinedValues) const override; 110409467b48Spatrick 110573471bf0Spatrick // Keep the zero-extensions for arguments to libcalls. shouldKeepZExtForFP16Conv()110673471bf0Spatrick bool shouldKeepZExtForFP16Conv() const override { return true; } 110773471bf0Spatrick 110809467b48Spatrick /// createFastISel - This method returns a target-specific FastISel object, 110909467b48Spatrick /// or null if the target does not support "fast" instruction selection. 111009467b48Spatrick FastISel *createFastISel(FunctionLoweringInfo &FuncInfo, 111109467b48Spatrick const TargetLibraryInfo *LibInfo) const override; 111209467b48Spatrick 111309467b48Spatrick /// Returns true if an argument of type Ty needs to be passed in a 111409467b48Spatrick /// contiguous block of registers in calling convention CallConv. functionArgumentNeedsConsecutiveRegisters(Type * Ty,CallingConv::ID CallConv,bool isVarArg,const DataLayout & DL)111509467b48Spatrick bool functionArgumentNeedsConsecutiveRegisters( 111673471bf0Spatrick Type *Ty, CallingConv::ID CallConv, bool isVarArg, 111773471bf0Spatrick const DataLayout &DL) const override { 111809467b48Spatrick // We support any array type as "consecutive" block in the parameter 111909467b48Spatrick // save area. The element type defines the alignment requirement and 112009467b48Spatrick // whether the argument should go in GPRs, FPRs, or VRs if available. 112109467b48Spatrick // 112209467b48Spatrick // Note that clang uses this capability both to implement the ELFv2 112309467b48Spatrick // homogeneous float/vector aggregate ABI, and to avoid having to use 112409467b48Spatrick // "byval" when passing aggregates that might fully fit in registers. 112509467b48Spatrick return Ty->isArrayTy(); 112609467b48Spatrick } 112709467b48Spatrick 112809467b48Spatrick /// If a physical register, this returns the register that receives the 112909467b48Spatrick /// exception address on entry to an EH pad. 1130097a140dSpatrick Register 113109467b48Spatrick getExceptionPointerRegister(const Constant *PersonalityFn) const override; 113209467b48Spatrick 113309467b48Spatrick /// If a physical register, this returns the register that receives the 113409467b48Spatrick /// exception typeid on entry to a landing pad. 1135097a140dSpatrick Register 113609467b48Spatrick getExceptionSelectorRegister(const Constant *PersonalityFn) const override; 113709467b48Spatrick 113809467b48Spatrick /// Override to support customized stack guard loading. 113909467b48Spatrick bool useLoadStackGuardNode() const override; 114009467b48Spatrick void insertSSPDeclarations(Module &M) const override; 114173471bf0Spatrick Value *getSDagStackGuard(const Module &M) const override; 114209467b48Spatrick 114309467b48Spatrick bool isFPImmLegal(const APFloat &Imm, EVT VT, 114409467b48Spatrick bool ForCodeSize) const override; 114509467b48Spatrick 114609467b48Spatrick unsigned getJumpTableEncoding() const override; 114709467b48Spatrick bool isJumpTableRelative() const override; 114809467b48Spatrick SDValue getPICJumpTableRelocBase(SDValue Table, 114909467b48Spatrick SelectionDAG &DAG) const override; 115009467b48Spatrick const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF, 115109467b48Spatrick unsigned JTI, 115209467b48Spatrick MCContext &Ctx) const override; 115309467b48Spatrick 115473471bf0Spatrick /// SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), 115573471bf0Spatrick /// compute the address flags of the node, get the optimal address mode 115673471bf0Spatrick /// based on the flags, and set the Base and Disp based on the address mode. 115773471bf0Spatrick PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, 115873471bf0Spatrick SDValue &Disp, SDValue &Base, 115973471bf0Spatrick SelectionDAG &DAG, 116073471bf0Spatrick MaybeAlign Align) const; 116173471bf0Spatrick /// SelectForceXFormMode - Given the specified address, force it to be 116273471bf0Spatrick /// represented as an indexed [r+r] operation (an XForm instruction). 116373471bf0Spatrick PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, 116473471bf0Spatrick SelectionDAG &DAG) const; 116573471bf0Spatrick 1166*d415bd75Srobert bool splitValueIntoRegisterParts( 1167*d415bd75Srobert SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, 1168*d415bd75Srobert unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) 1169*d415bd75Srobert const override; 1170097a140dSpatrick /// Structure that collects some common arguments that get passed around 1171097a140dSpatrick /// between the functions for call lowering. 1172097a140dSpatrick struct CallFlags { 1173097a140dSpatrick const CallingConv::ID CallConv; 1174097a140dSpatrick const bool IsTailCall : 1; 1175097a140dSpatrick const bool IsVarArg : 1; 1176097a140dSpatrick const bool IsPatchPoint : 1; 1177097a140dSpatrick const bool IsIndirect : 1; 1178097a140dSpatrick const bool HasNest : 1; 1179097a140dSpatrick const bool NoMerge : 1; 1180097a140dSpatrick CallFlagsCallFlags1181097a140dSpatrick CallFlags(CallingConv::ID CC, bool IsTailCall, bool IsVarArg, 1182097a140dSpatrick bool IsPatchPoint, bool IsIndirect, bool HasNest, bool NoMerge) 1183097a140dSpatrick : CallConv(CC), IsTailCall(IsTailCall), IsVarArg(IsVarArg), 1184097a140dSpatrick IsPatchPoint(IsPatchPoint), IsIndirect(IsIndirect), 1185097a140dSpatrick HasNest(HasNest), NoMerge(NoMerge) {} 1186097a140dSpatrick }; 1187097a140dSpatrick 118873471bf0Spatrick CCAssignFn *ccAssignFnForCall(CallingConv::ID CC, bool Return, 118973471bf0Spatrick bool IsVarArg) const; 119073471bf0Spatrick 119109467b48Spatrick private: 119209467b48Spatrick struct ReuseLoadInfo { 119309467b48Spatrick SDValue Ptr; 119409467b48Spatrick SDValue Chain; 119509467b48Spatrick SDValue ResChain; 119609467b48Spatrick MachinePointerInfo MPI; 119709467b48Spatrick bool IsDereferenceable = false; 119809467b48Spatrick bool IsInvariant = false; 1199097a140dSpatrick Align Alignment; 120009467b48Spatrick AAMDNodes AAInfo; 120109467b48Spatrick const MDNode *Ranges = nullptr; 120209467b48Spatrick 120309467b48Spatrick ReuseLoadInfo() = default; 120409467b48Spatrick MMOFlagsReuseLoadInfo120509467b48Spatrick MachineMemOperand::Flags MMOFlags() const { 120609467b48Spatrick MachineMemOperand::Flags F = MachineMemOperand::MONone; 120709467b48Spatrick if (IsDereferenceable) 120809467b48Spatrick F |= MachineMemOperand::MODereferenceable; 120909467b48Spatrick if (IsInvariant) 121009467b48Spatrick F |= MachineMemOperand::MOInvariant; 121109467b48Spatrick return F; 121209467b48Spatrick } 121309467b48Spatrick }; 121409467b48Spatrick 121573471bf0Spatrick // Map that relates a set of common address flags to PPC addressing modes. 121673471bf0Spatrick std::map<PPC::AddrMode, SmallVector<unsigned, 16>> AddrModesMap; 121773471bf0Spatrick void initializeAddrModeMap(); 121809467b48Spatrick 121909467b48Spatrick bool canReuseLoadAddress(SDValue Op, EVT MemVT, ReuseLoadInfo &RLI, 122009467b48Spatrick SelectionDAG &DAG, 122109467b48Spatrick ISD::LoadExtType ET = ISD::NON_EXTLOAD) const; 122209467b48Spatrick void spliceIntoChain(SDValue ResChain, SDValue NewResChain, 122309467b48Spatrick SelectionDAG &DAG) const; 122409467b48Spatrick 122509467b48Spatrick void LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI, 122609467b48Spatrick SelectionDAG &DAG, const SDLoc &dl) const; 122709467b48Spatrick SDValue LowerFP_TO_INTDirectMove(SDValue Op, SelectionDAG &DAG, 122809467b48Spatrick const SDLoc &dl) const; 122909467b48Spatrick 123009467b48Spatrick bool directMoveIsProfitable(const SDValue &Op) const; 123109467b48Spatrick SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG &DAG, 123209467b48Spatrick const SDLoc &dl) const; 123309467b48Spatrick 123409467b48Spatrick SDValue LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG, 123509467b48Spatrick const SDLoc &dl) const; 123609467b48Spatrick 123709467b48Spatrick SDValue LowerTRUNCATEVector(SDValue Op, SelectionDAG &DAG) const; 123809467b48Spatrick 123909467b48Spatrick SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const; 124009467b48Spatrick SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const; 124109467b48Spatrick 124209467b48Spatrick bool 124309467b48Spatrick IsEligibleForTailCallOptimization(SDValue Callee, 124409467b48Spatrick CallingConv::ID CalleeCC, 124509467b48Spatrick bool isVarArg, 124609467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 124709467b48Spatrick SelectionDAG& DAG) const; 124809467b48Spatrick 1249097a140dSpatrick bool IsEligibleForTailCallOptimization_64SVR4( 1250097a140dSpatrick SDValue Callee, CallingConv::ID CalleeCC, const CallBase *CB, 1251097a140dSpatrick bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs, 1252097a140dSpatrick const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const; 125309467b48Spatrick 125409467b48Spatrick SDValue EmitTailCallLoadFPAndRetAddr(SelectionDAG &DAG, int SPDiff, 125509467b48Spatrick SDValue Chain, SDValue &LROpOut, 125609467b48Spatrick SDValue &FPOpOut, 125709467b48Spatrick const SDLoc &dl) const; 125809467b48Spatrick 125909467b48Spatrick SDValue getTOCEntry(SelectionDAG &DAG, const SDLoc &dl, SDValue GA) const; 126009467b48Spatrick 126109467b48Spatrick SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 126209467b48Spatrick SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 126309467b48Spatrick SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 126409467b48Spatrick SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 126509467b48Spatrick SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 126673471bf0Spatrick SDValue LowerGlobalTLSAddressAIX(SDValue Op, SelectionDAG &DAG) const; 126773471bf0Spatrick SDValue LowerGlobalTLSAddressLinux(SDValue Op, SelectionDAG &DAG) const; 126809467b48Spatrick SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 126909467b48Spatrick SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 127009467b48Spatrick SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 127109467b48Spatrick SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; 127209467b48Spatrick SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; 127373471bf0Spatrick SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; 127409467b48Spatrick SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 127509467b48Spatrick SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; 127609467b48Spatrick SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const; 127709467b48Spatrick SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; 127809467b48Spatrick SDValue LowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const; 127909467b48Spatrick SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 128009467b48Spatrick SDValue LowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; 128109467b48Spatrick SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; 128209467b48Spatrick SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; 128309467b48Spatrick SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const; 128409467b48Spatrick SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 128509467b48Spatrick SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, 128609467b48Spatrick const SDLoc &dl) const; 128709467b48Spatrick SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 1288*d415bd75Srobert SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const; 128909467b48Spatrick SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const; 129009467b48Spatrick SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const; 129109467b48Spatrick SDValue LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const; 129273471bf0Spatrick SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) const; 129309467b48Spatrick SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 129409467b48Spatrick SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; 1295*d415bd75Srobert SDValue LowerVPERM(SDValue Op, SelectionDAG &DAG, ArrayRef<int> PermMask, 1296*d415bd75Srobert EVT VT, SDValue V1, SDValue V2) const; 129709467b48Spatrick SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 129809467b48Spatrick SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 129909467b48Spatrick SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; 130009467b48Spatrick SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const; 130109467b48Spatrick SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const; 1302*d415bd75Srobert SDValue lowerToLibCall(const char *LibCallName, SDValue Op, 1303*d415bd75Srobert SelectionDAG &DAG) const; 1304*d415bd75Srobert SDValue lowerLibCallBasedOnType(const char *LibCallFloatName, 1305*d415bd75Srobert const char *LibCallDoubleName, SDValue Op, 1306*d415bd75Srobert SelectionDAG &DAG) const; 1307*d415bd75Srobert bool isLowringToMASSFiniteSafe(SDValue Op) const; 1308*d415bd75Srobert bool isLowringToMASSSafe(SDValue Op) const; 1309*d415bd75Srobert bool isScalarMASSConversionEnabled() const; 1310*d415bd75Srobert SDValue lowerLibCallBase(const char *LibCallDoubleName, 1311*d415bd75Srobert const char *LibCallFloatName, 1312*d415bd75Srobert const char *LibCallDoubleNameFinite, 1313*d415bd75Srobert const char *LibCallFloatNameFinite, SDValue Op, 1314*d415bd75Srobert SelectionDAG &DAG) const; 1315*d415bd75Srobert SDValue lowerPow(SDValue Op, SelectionDAG &DAG) const; 1316*d415bd75Srobert SDValue lowerSin(SDValue Op, SelectionDAG &DAG) const; 1317*d415bd75Srobert SDValue lowerCos(SDValue Op, SelectionDAG &DAG) const; 1318*d415bd75Srobert SDValue lowerLog(SDValue Op, SelectionDAG &DAG) const; 1319*d415bd75Srobert SDValue lowerLog10(SDValue Op, SelectionDAG &DAG) const; 1320*d415bd75Srobert SDValue lowerExp(SDValue Op, SelectionDAG &DAG) const; 1321*d415bd75Srobert SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) const; 132209467b48Spatrick SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const; 132309467b48Spatrick SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const; 132409467b48Spatrick SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const; 132573471bf0Spatrick SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const; 1326097a140dSpatrick SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const; 132709467b48Spatrick 132809467b48Spatrick SDValue LowerVectorLoad(SDValue Op, SelectionDAG &DAG) const; 132909467b48Spatrick SDValue LowerVectorStore(SDValue Op, SelectionDAG &DAG) const; 133009467b48Spatrick 133109467b48Spatrick SDValue LowerCallResult(SDValue Chain, SDValue InFlag, 133209467b48Spatrick CallingConv::ID CallConv, bool isVarArg, 133309467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 133409467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 133509467b48Spatrick SmallVectorImpl<SDValue> &InVals) const; 1336097a140dSpatrick 1337097a140dSpatrick SDValue FinishCall(CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, 133809467b48Spatrick SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, 133909467b48Spatrick SDValue InFlag, SDValue Chain, SDValue CallSeqStart, 134009467b48Spatrick SDValue &Callee, int SPDiff, unsigned NumBytes, 134109467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 134209467b48Spatrick SmallVectorImpl<SDValue> &InVals, 1343097a140dSpatrick const CallBase *CB) const; 134409467b48Spatrick 134509467b48Spatrick SDValue 134609467b48Spatrick LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 134709467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 134809467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 134909467b48Spatrick SmallVectorImpl<SDValue> &InVals) const override; 135009467b48Spatrick 135109467b48Spatrick SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 135209467b48Spatrick SmallVectorImpl<SDValue> &InVals) const override; 135309467b48Spatrick 135409467b48Spatrick bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 135509467b48Spatrick bool isVarArg, 135609467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 135709467b48Spatrick LLVMContext &Context) const override; 135809467b48Spatrick 135909467b48Spatrick SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 136009467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 136109467b48Spatrick const SmallVectorImpl<SDValue> &OutVals, 136209467b48Spatrick const SDLoc &dl, SelectionDAG &DAG) const override; 136309467b48Spatrick 136409467b48Spatrick SDValue extendArgForPPC64(ISD::ArgFlagsTy Flags, EVT ObjectVT, 136509467b48Spatrick SelectionDAG &DAG, SDValue ArgVal, 136609467b48Spatrick const SDLoc &dl) const; 136709467b48Spatrick 136809467b48Spatrick SDValue LowerFormalArguments_AIX( 136909467b48Spatrick SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 137009467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 137109467b48Spatrick SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; 137209467b48Spatrick SDValue LowerFormalArguments_64SVR4( 137309467b48Spatrick SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 137409467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 137509467b48Spatrick SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; 137609467b48Spatrick SDValue LowerFormalArguments_32SVR4( 137709467b48Spatrick SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 137809467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 137909467b48Spatrick SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; 138009467b48Spatrick 138109467b48Spatrick SDValue createMemcpyOutsideCallSeq(SDValue Arg, SDValue PtrOff, 138209467b48Spatrick SDValue CallSeqStart, 138309467b48Spatrick ISD::ArgFlagsTy Flags, SelectionDAG &DAG, 138409467b48Spatrick const SDLoc &dl) const; 138509467b48Spatrick 1386097a140dSpatrick SDValue LowerCall_64SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags, 138709467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 138809467b48Spatrick const SmallVectorImpl<SDValue> &OutVals, 138909467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 139009467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 139109467b48Spatrick SmallVectorImpl<SDValue> &InVals, 1392097a140dSpatrick const CallBase *CB) const; 1393097a140dSpatrick SDValue LowerCall_32SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags, 139409467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 139509467b48Spatrick const SmallVectorImpl<SDValue> &OutVals, 139609467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 139709467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 139809467b48Spatrick SmallVectorImpl<SDValue> &InVals, 1399097a140dSpatrick const CallBase *CB) const; 1400097a140dSpatrick SDValue LowerCall_AIX(SDValue Chain, SDValue Callee, CallFlags CFlags, 140109467b48Spatrick const SmallVectorImpl<ISD::OutputArg> &Outs, 140209467b48Spatrick const SmallVectorImpl<SDValue> &OutVals, 140309467b48Spatrick const SmallVectorImpl<ISD::InputArg> &Ins, 140409467b48Spatrick const SDLoc &dl, SelectionDAG &DAG, 140509467b48Spatrick SmallVectorImpl<SDValue> &InVals, 1406097a140dSpatrick const CallBase *CB) const; 140709467b48Spatrick 140809467b48Spatrick SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 140909467b48Spatrick SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 141009467b48Spatrick SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const; 141109467b48Spatrick 141209467b48Spatrick SDValue DAGCombineExtBoolTrunc(SDNode *N, DAGCombinerInfo &DCI) const; 141309467b48Spatrick SDValue DAGCombineBuildVector(SDNode *N, DAGCombinerInfo &DCI) const; 141409467b48Spatrick SDValue DAGCombineTruncBoolExt(SDNode *N, DAGCombinerInfo &DCI) const; 141509467b48Spatrick SDValue combineStoreFPToInt(SDNode *N, DAGCombinerInfo &DCI) const; 141609467b48Spatrick SDValue combineFPToIntToFP(SDNode *N, DAGCombinerInfo &DCI) const; 141709467b48Spatrick SDValue combineSHL(SDNode *N, DAGCombinerInfo &DCI) const; 141809467b48Spatrick SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const; 141909467b48Spatrick SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const; 142009467b48Spatrick SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const; 142109467b48Spatrick SDValue combineADD(SDNode *N, DAGCombinerInfo &DCI) const; 1422097a140dSpatrick SDValue combineFMALike(SDNode *N, DAGCombinerInfo &DCI) const; 142309467b48Spatrick SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 142409467b48Spatrick SDValue combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const; 142509467b48Spatrick SDValue combineABS(SDNode *N, DAGCombinerInfo &DCI) const; 142609467b48Spatrick SDValue combineVSelect(SDNode *N, DAGCombinerInfo &DCI) const; 1427097a140dSpatrick SDValue combineVectorShuffle(ShuffleVectorSDNode *SVN, 1428097a140dSpatrick SelectionDAG &DAG) const; 142909467b48Spatrick SDValue combineVReverseMemOP(ShuffleVectorSDNode *SVN, LSBaseSDNode *LSBase, 143009467b48Spatrick DAGCombinerInfo &DCI) const; 143109467b48Spatrick 143209467b48Spatrick /// ConvertSETCCToSubtract - looks at SETCC that compares ints. It replaces 143309467b48Spatrick /// SETCC with integer subtraction when (1) there is a legal way of doing it 143409467b48Spatrick /// (2) keeping the result of comparison in GPR has performance benefit. 143509467b48Spatrick SDValue ConvertSETCCToSubtract(SDNode *N, DAGCombinerInfo &DCI) const; 143609467b48Spatrick 143709467b48Spatrick SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, 143809467b48Spatrick int &RefinementSteps, bool &UseOneConstNR, 143909467b48Spatrick bool Reciprocal) const override; 144009467b48Spatrick SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, 144109467b48Spatrick int &RefinementSteps) const override; 144273471bf0Spatrick SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, 144373471bf0Spatrick const DenormalMode &Mode) const override; 144473471bf0Spatrick SDValue getSqrtResultForDenormInput(SDValue Operand, 144573471bf0Spatrick SelectionDAG &DAG) const override; 144609467b48Spatrick unsigned combineRepeatedFPDivisors() const override; 144709467b48Spatrick 144809467b48Spatrick SDValue 144909467b48Spatrick combineElementTruncationToVectorTruncation(SDNode *N, 145009467b48Spatrick DAGCombinerInfo &DCI) const; 145109467b48Spatrick 145209467b48Spatrick /// lowerToVINSERTH - Return the SDValue if this VECTOR_SHUFFLE can be 145309467b48Spatrick /// handled by the VINSERTH instruction introduced in ISA 3.0. This is 145409467b48Spatrick /// essentially any shuffle of v8i16 vectors that just inserts one element 145509467b48Spatrick /// from one vector into the other. 145609467b48Spatrick SDValue lowerToVINSERTH(ShuffleVectorSDNode *N, SelectionDAG &DAG) const; 145709467b48Spatrick 145809467b48Spatrick /// lowerToVINSERTB - Return the SDValue if this VECTOR_SHUFFLE can be 145909467b48Spatrick /// handled by the VINSERTB instruction introduced in ISA 3.0. This is 146009467b48Spatrick /// essentially v16i8 vector version of VINSERTH. 146109467b48Spatrick SDValue lowerToVINSERTB(ShuffleVectorSDNode *N, SelectionDAG &DAG) const; 146209467b48Spatrick 1463097a140dSpatrick /// lowerToXXSPLTI32DX - Return the SDValue if this VECTOR_SHUFFLE can be 1464097a140dSpatrick /// handled by the XXSPLTI32DX instruction introduced in ISA 3.1. 1465097a140dSpatrick SDValue lowerToXXSPLTI32DX(ShuffleVectorSDNode *N, SelectionDAG &DAG) const; 1466097a140dSpatrick 146709467b48Spatrick // Return whether the call instruction can potentially be optimized to a 146809467b48Spatrick // tail call. This will cause the optimizers to attempt to move, or 146909467b48Spatrick // duplicate return instructions to help enable tail call optimizations. 147009467b48Spatrick bool mayBeEmittedAsTailCall(const CallInst *CI) const override; 147109467b48Spatrick bool hasBitPreservingFPLogic(EVT VT) const override; 147209467b48Spatrick bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override; 147373471bf0Spatrick 147473471bf0Spatrick /// getAddrModeForFlags - Based on the set of address flags, select the most 147573471bf0Spatrick /// optimal instruction format to match by. 147673471bf0Spatrick PPC::AddrMode getAddrModeForFlags(unsigned Flags) const; 147773471bf0Spatrick 147873471bf0Spatrick /// computeMOFlags - Given a node N and it's Parent (a MemSDNode), compute 147973471bf0Spatrick /// the address flags of the load/store instruction that is to be matched. 148073471bf0Spatrick /// The address flags are stored in a map, which is then searched 148173471bf0Spatrick /// through to determine the optimal load/store instruction format. 148273471bf0Spatrick unsigned computeMOFlags(const SDNode *Parent, SDValue N, 148373471bf0Spatrick SelectionDAG &DAG) const; 148409467b48Spatrick }; // end class PPCTargetLowering 148509467b48Spatrick 148609467b48Spatrick namespace PPC { 148709467b48Spatrick 148809467b48Spatrick FastISel *createFastISel(FunctionLoweringInfo &FuncInfo, 148909467b48Spatrick const TargetLibraryInfo *LibInfo); 149009467b48Spatrick 149109467b48Spatrick } // end namespace PPC 149209467b48Spatrick 149309467b48Spatrick bool isIntS16Immediate(SDNode *N, int16_t &Imm); 149409467b48Spatrick bool isIntS16Immediate(SDValue Op, int16_t &Imm); 149573471bf0Spatrick bool isIntS34Immediate(SDNode *N, int64_t &Imm); 149673471bf0Spatrick bool isIntS34Immediate(SDValue Op, int64_t &Imm); 149709467b48Spatrick 1498097a140dSpatrick bool convertToNonDenormSingle(APInt &ArgAPInt); 1499097a140dSpatrick bool convertToNonDenormSingle(APFloat &ArgAPFloat); 150073471bf0Spatrick bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat); 1501097a140dSpatrick 150209467b48Spatrick } // end namespace llvm 150309467b48Spatrick 1504*d415bd75Srobert #endif // LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H 1505