10b57cec5SDimitry Andric //===-- PPCISelLowering.h - PPC32 DAG Lowering Interface --------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the interfaces that PPC uses to lower LLVM code into a 100b57cec5SDimitry Andric // selection DAG. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H 150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "PPCInstrInfo.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/ValueTypes.h" 25*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h" 260b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 270b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h" 280b57cec5SDimitry Andric #include "llvm/IR/Function.h" 290b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h" 300b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 310b57cec5SDimitry Andric #include "llvm/IR/Type.h" 32bdd1243dSDimitry Andric #include <optional> 330b57cec5SDimitry Andric #include <utility> 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric namespace llvm { 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric namespace PPCISD { 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // When adding a NEW PPCISD node please add it to the correct position in 400b57cec5SDimitry Andric // the enum. The order of elements in this enum matters! 410b57cec5SDimitry Andric // Values that are added after this entry: 420b57cec5SDimitry Andric // STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE 430b57cec5SDimitry Andric // are considered memory opcodes and are treated differently than entries 440b57cec5SDimitry Andric // that come before it. For example, ADD or MUL should be placed before 450b57cec5SDimitry Andric // the ISD::FIRST_TARGET_MEMORY_OPCODE while a LOAD or STORE should come 460b57cec5SDimitry Andric // after it. 470b57cec5SDimitry Andric enum NodeType : unsigned { 480b57cec5SDimitry Andric // Start the numbering where the builtin ops and target ops leave off. 490b57cec5SDimitry Andric FIRST_NUMBER = ISD::BUILTIN_OP_END, 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric /// FSEL - Traditional three-operand fsel node. 520b57cec5SDimitry Andric /// 530b57cec5SDimitry Andric FSEL, 540b57cec5SDimitry Andric 5581ad6265SDimitry Andric /// XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions. 5681ad6265SDimitry Andric XSMAXC, 5781ad6265SDimitry Andric XSMINC, 58480093f4SDimitry Andric 590b57cec5SDimitry Andric /// FCFID - The FCFID instruction, taking an f64 operand and producing 600b57cec5SDimitry Andric /// and f64 value containing the FP representation of the integer that 610b57cec5SDimitry Andric /// was temporarily in the f64 operand. 620b57cec5SDimitry Andric FCFID, 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric /// Newer FCFID[US] integer-to-floating-point conversion instructions for 650b57cec5SDimitry Andric /// unsigned integers and single-precision outputs. 66480093f4SDimitry Andric FCFIDU, 67480093f4SDimitry Andric FCFIDS, 68480093f4SDimitry Andric FCFIDUS, 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 710b57cec5SDimitry Andric /// operand, producing an f64 value containing the integer representation 720b57cec5SDimitry Andric /// of that FP value. 73480093f4SDimitry Andric FCTIDZ, 74480093f4SDimitry Andric FCTIWZ, 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for 770b57cec5SDimitry Andric /// unsigned integers with round toward zero. 78480093f4SDimitry Andric FCTIDUZ, 79480093f4SDimitry Andric FCTIWUZ, 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// VEXTS, ByteWidth - takes an input in VSFRC and produces an output in 820b57cec5SDimitry Andric /// VSFRC that is sign-extended from ByteWidth to a 64-byte integer. 830b57cec5SDimitry Andric VEXTS, 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// Reciprocal estimate instructions (unary FP ops). 86480093f4SDimitry Andric FRE, 87480093f4SDimitry Andric FRSQRTE, 880b57cec5SDimitry Andric 89e8d8bef9SDimitry Andric /// Test instruction for software square root. 90e8d8bef9SDimitry Andric FTSQRT, 91e8d8bef9SDimitry Andric 92e8d8bef9SDimitry Andric /// Square root instruction. 93e8d8bef9SDimitry Andric FSQRT, 94e8d8bef9SDimitry Andric 950b57cec5SDimitry Andric /// VPERM - The PPC VPERM Instruction. 960b57cec5SDimitry Andric /// 970b57cec5SDimitry Andric VPERM, 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric /// XXSPLT - The PPC VSX splat instructions 1000b57cec5SDimitry Andric /// 1010b57cec5SDimitry Andric XXSPLT, 1020b57cec5SDimitry Andric 1035ffd83dbSDimitry Andric /// XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for 1045ffd83dbSDimitry Andric /// converting immediate single precision numbers to double precision 1055ffd83dbSDimitry Andric /// vector or scalar. 1065ffd83dbSDimitry Andric XXSPLTI_SP_TO_DP, 1075ffd83dbSDimitry Andric 1085ffd83dbSDimitry Andric /// XXSPLTI32DX - The PPC XXSPLTI32DX instruction. 1095ffd83dbSDimitry Andric /// 1105ffd83dbSDimitry Andric XXSPLTI32DX, 1115ffd83dbSDimitry Andric 1120b57cec5SDimitry Andric /// VECINSERT - The PPC vector insert instruction 1130b57cec5SDimitry Andric /// 1140b57cec5SDimitry Andric VECINSERT, 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric /// VECSHL - The PPC vector shift left instruction 1170b57cec5SDimitry Andric /// 1180b57cec5SDimitry Andric VECSHL, 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric /// XXPERMDI - The PPC XXPERMDI instruction 1210b57cec5SDimitry Andric /// 1220b57cec5SDimitry Andric XXPERMDI, 123bdd1243dSDimitry Andric XXPERM, 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// The CMPB instruction (takes two operands of i32 or i64). 1260b57cec5SDimitry Andric CMPB, 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// Hi/Lo - These represent the high and low 16-bit parts of a global 1290b57cec5SDimitry Andric /// address respectively. These nodes have two operands, the first of 1300b57cec5SDimitry Andric /// which must be a TargetGlobalAddress, and the second of which must be a 1310b57cec5SDimitry Andric /// Constant. Selected naively, these turn into 'lis G+C' and 'li G+C', 1320b57cec5SDimitry Andric /// though these are usually folded into other nodes. 133480093f4SDimitry Andric Hi, 134480093f4SDimitry Andric Lo, 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric /// The following two target-specific nodes are used for calls through 1370b57cec5SDimitry Andric /// function pointers in the 64-bit SVR4 ABI. 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric /// OPRC, CHAIN = DYNALLOC(CHAIN, NEGSIZE, FRAME_INDEX) 1400b57cec5SDimitry Andric /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to 1410b57cec5SDimitry Andric /// compute an allocation on the stack. 1420b57cec5SDimitry Andric DYNALLOC, 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to 1450b57cec5SDimitry Andric /// compute an offset from native SP to the address of the most recent 1460b57cec5SDimitry Andric /// dynamic alloca. 1470b57cec5SDimitry Andric DYNAREAOFFSET, 1480b57cec5SDimitry Andric 1495ffd83dbSDimitry Andric /// To avoid stack clash, allocation is performed by block and each block is 1505ffd83dbSDimitry Andric /// probed. 1515ffd83dbSDimitry Andric PROBED_ALLOCA, 1525ffd83dbSDimitry Andric 153e8d8bef9SDimitry Andric /// The result of the mflr at function entry, used for PIC code. 1540b57cec5SDimitry Andric GlobalBaseReg, 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric /// These nodes represent PPC shifts. 1570b57cec5SDimitry Andric /// 1580b57cec5SDimitry Andric /// For scalar types, only the last `n + 1` bits of the shift amounts 1590b57cec5SDimitry Andric /// are used, where n is log2(sizeof(element) * 8). See sld/slw, etc. 1600b57cec5SDimitry Andric /// for exact behaviors. 1610b57cec5SDimitry Andric /// 1620b57cec5SDimitry Andric /// For vector types, only the last n bits are used. See vsld. 163480093f4SDimitry Andric SRL, 164480093f4SDimitry Andric SRA, 165480093f4SDimitry Andric SHL, 1660b57cec5SDimitry Andric 1675ffd83dbSDimitry Andric /// FNMSUB - Negated multiply-subtract instruction. 1685ffd83dbSDimitry Andric FNMSUB, 1695ffd83dbSDimitry Andric 1700b57cec5SDimitry Andric /// EXTSWSLI = The PPC extswsli instruction, which does an extend-sign 1710b57cec5SDimitry Andric /// word and shift left immediate. 1720b57cec5SDimitry Andric EXTSWSLI, 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric /// The combination of sra[wd]i and addze used to implemented signed 1750b57cec5SDimitry Andric /// integer division by a power of 2. The first operand is the dividend, 1760b57cec5SDimitry Andric /// and the second is the constant shift amount (representing the 1770b57cec5SDimitry Andric /// divisor). 1780b57cec5SDimitry Andric SRA_ADDZE, 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// CALL - A direct function call. 1810b57cec5SDimitry Andric /// CALL_NOP is a call with the special NOP which follows 64-bit 1825ffd83dbSDimitry Andric /// CALL_NOTOC the caller does not use the TOC. 1830b57cec5SDimitry Andric /// SVR4 calls and 32-bit/64-bit AIX calls. 184480093f4SDimitry Andric CALL, 185480093f4SDimitry Andric CALL_NOP, 1865ffd83dbSDimitry Andric CALL_NOTOC, 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a 1890b57cec5SDimitry Andric /// MTCTR instruction. 1900b57cec5SDimitry Andric MTCTR, 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a 1930b57cec5SDimitry Andric /// BCTRL instruction. 1940b57cec5SDimitry Andric BCTRL, 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl 197480093f4SDimitry Andric /// instruction and the TOC reload required on 64-bit ELF, 32-bit AIX 198480093f4SDimitry Andric /// and 64-bit AIX. 1990b57cec5SDimitry Andric BCTRL_LOAD_TOC, 2000b57cec5SDimitry Andric 201349cc55cSDimitry Andric /// The variants that implicitly define rounding mode for calls with 202349cc55cSDimitry Andric /// strictfp semantics. 203349cc55cSDimitry Andric CALL_RM, 204349cc55cSDimitry Andric CALL_NOP_RM, 205349cc55cSDimitry Andric CALL_NOTOC_RM, 206349cc55cSDimitry Andric BCTRL_RM, 207349cc55cSDimitry Andric BCTRL_LOAD_TOC_RM, 208349cc55cSDimitry Andric 20906c3fb27SDimitry Andric /// Return with a glue operand, matched by 'blr' 21006c3fb27SDimitry Andric RET_GLUE, 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric /// R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction. 2130b57cec5SDimitry Andric /// This copies the bits corresponding to the specified CRREG into the 2140b57cec5SDimitry Andric /// resultant GPR. Bits corresponding to other CR regs are undefined. 2150b57cec5SDimitry Andric MFOCRF, 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric /// Direct move from a VSX register to a GPR 2180b57cec5SDimitry Andric MFVSR, 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric /// Direct move from a GPR to a VSX register (algebraic) 2210b57cec5SDimitry Andric MTVSRA, 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric /// Direct move from a GPR to a VSX register (zero) 2240b57cec5SDimitry Andric MTVSRZ, 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric /// Direct move of 2 consecutive GPR to a VSX register. 2270b57cec5SDimitry Andric BUILD_FP128, 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and 2300b57cec5SDimitry Andric /// EXTRACT_ELEMENT but take f64 arguments instead of i64, as i64 is 2310b57cec5SDimitry Andric /// unsupported for this target. 2320b57cec5SDimitry Andric /// Merge 2 GPRs to a single SPE register. 2330b57cec5SDimitry Andric BUILD_SPE64, 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric /// Extract SPE register component, second argument is high or low. 2360b57cec5SDimitry Andric EXTRACT_SPE, 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric /// Extract a subvector from signed integer vector and convert to FP. 2390b57cec5SDimitry Andric /// It is primarily used to convert a (widened) illegal integer vector 2400b57cec5SDimitry Andric /// type to a legal floating point vector type. 2410b57cec5SDimitry Andric /// For example v2i32 -> widened to v4i32 -> v2f64 2420b57cec5SDimitry Andric SINT_VEC_TO_FP, 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric /// Extract a subvector from unsigned integer vector and convert to FP. 2450b57cec5SDimitry Andric /// As with SINT_VEC_TO_FP, used for converting illegal types. 2460b57cec5SDimitry Andric UINT_VEC_TO_FP, 2470b57cec5SDimitry Andric 2485ffd83dbSDimitry Andric /// PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to 2495ffd83dbSDimitry Andric /// place the value into the least significant element of the most 2505ffd83dbSDimitry Andric /// significant doubleword in the vector. This is not element zero for 2515ffd83dbSDimitry Andric /// anything smaller than a doubleword on either endianness. This node has 2525ffd83dbSDimitry Andric /// the same semantics as SCALAR_TO_VECTOR except that the value remains in 2535ffd83dbSDimitry Andric /// the aforementioned location in the vector register. 2545ffd83dbSDimitry Andric SCALAR_TO_VECTOR_PERMUTED, 2555ffd83dbSDimitry Andric 2560b57cec5SDimitry Andric // FIXME: Remove these once the ANDI glue bug is fixed: 257480093f4SDimitry Andric /// i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the 2580b57cec5SDimitry Andric /// eq or gt bit of CR0 after executing andi. x, 1. This is used to 2590b57cec5SDimitry Andric /// implement truncation of i32 or i64 to i1. 260480093f4SDimitry Andric ANDI_rec_1_EQ_BIT, 261480093f4SDimitry Andric ANDI_rec_1_GT_BIT, 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric // READ_TIME_BASE - A read of the 64-bit time-base register on a 32-bit 2640b57cec5SDimitry Andric // target (returns (Lo, Hi)). It takes a chain operand. 2650b57cec5SDimitry Andric READ_TIME_BASE, 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric // EH_SJLJ_SETJMP - SjLj exception handling setjmp. 2680b57cec5SDimitry Andric EH_SJLJ_SETJMP, 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // EH_SJLJ_LONGJMP - SjLj exception handling longjmp. 2710b57cec5SDimitry Andric EH_SJLJ_LONGJMP, 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric /// RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* 2740b57cec5SDimitry Andric /// instructions. For lack of better number, we use the opcode number 2750b57cec5SDimitry Andric /// encoding for the OPC field to identify the compare. For example, 838 2760b57cec5SDimitry Andric /// is VCMPGTSH. 2770b57cec5SDimitry Andric VCMP, 2780b57cec5SDimitry Andric 279e8d8bef9SDimitry Andric /// RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the 280e8d8bef9SDimitry Andric /// altivec VCMP*_rec instructions. For lack of better number, we use the 2810b57cec5SDimitry Andric /// opcode number encoding for the OPC field to identify the compare. For 2820b57cec5SDimitry Andric /// example, 838 is VCMPGTSH. 283e8d8bef9SDimitry Andric VCMP_rec, 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric /// CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This 2860b57cec5SDimitry Andric /// corresponds to the COND_BRANCH pseudo instruction. CRRC is the 2870b57cec5SDimitry Andric /// condition register to branch on, OPC is the branch opcode to use (e.g. 2880b57cec5SDimitry Andric /// PPC::BLE), DESTBB is the destination block to branch to, and INFLAG is 2890b57cec5SDimitry Andric /// an optional input flag argument. 2900b57cec5SDimitry Andric COND_BRANCH, 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric /// CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based 2930b57cec5SDimitry Andric /// loops. 294480093f4SDimitry Andric BDNZ, 295480093f4SDimitry Andric BDZ, 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric /// F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding 2980b57cec5SDimitry Andric /// towards zero. Used only as part of the long double-to-int 2990b57cec5SDimitry Andric /// conversion sequence. 3000b57cec5SDimitry Andric FADDRTZ, 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric /// F8RC = MFFS - This moves the FPSCR (not modeled) into the register. 3030b57cec5SDimitry Andric MFFS, 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric /// TC_RETURN - A tail call return. 3060b57cec5SDimitry Andric /// operand #0 chain 3070b57cec5SDimitry Andric /// operand #1 callee (register or absolute) 3080b57cec5SDimitry Andric /// operand #2 stack adjustment 3090b57cec5SDimitry Andric /// operand #3 optional in flag 3100b57cec5SDimitry Andric TC_RETURN, 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric /// ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls 3130b57cec5SDimitry Andric CR6SET, 3140b57cec5SDimitry Andric CR6UNSET, 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by initial-exec TLS 3170b57cec5SDimitry Andric /// for non-position independent code on PPC32. 3180b57cec5SDimitry Andric PPC32_GOT, 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and 3210b57cec5SDimitry Andric /// local dynamic TLS and position indendepent code on PPC32. 3220b57cec5SDimitry Andric PPC32_PICGOT, 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric /// G8RC = ADDIS_GOT_TPREL_HA %x2, Symbol - Used by the initial-exec 3250b57cec5SDimitry Andric /// TLS model, produces an ADDIS8 instruction that adds the GOT 3260b57cec5SDimitry Andric /// base to sym\@got\@tprel\@ha. 3270b57cec5SDimitry Andric ADDIS_GOT_TPREL_HA, 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric /// G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec 3300b57cec5SDimitry Andric /// TLS model, produces a LD instruction with base register G8RReg 3310b57cec5SDimitry Andric /// and offset sym\@got\@tprel\@l. This completes the addition that 3320b57cec5SDimitry Andric /// finds the offset of "sym" relative to the thread pointer. 3330b57cec5SDimitry Andric LD_GOT_TPREL_L, 3340b57cec5SDimitry Andric 33506c3fb27SDimitry Andric /// G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec 33606c3fb27SDimitry Andric /// and local-exec TLS models, produces an ADD instruction that adds 33706c3fb27SDimitry Andric /// the contents of G8RReg to the thread pointer. Symbol contains a 33806c3fb27SDimitry Andric /// relocation sym\@tls which is to be replaced by the thread pointer 33906c3fb27SDimitry Andric /// and identifies to the linker that the instruction is part of a 3400b57cec5SDimitry Andric /// TLS sequence. 3410b57cec5SDimitry Andric ADD_TLS, 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric /// G8RC = ADDIS_TLSGD_HA %x2, Symbol - For the general-dynamic TLS 3440b57cec5SDimitry Andric /// model, produces an ADDIS8 instruction that adds the GOT base 3450b57cec5SDimitry Andric /// register to sym\@got\@tlsgd\@ha. 3460b57cec5SDimitry Andric ADDIS_TLSGD_HA, 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric /// %x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS 3490b57cec5SDimitry Andric /// model, produces an ADDI8 instruction that adds G8RReg to 3500b57cec5SDimitry Andric /// sym\@got\@tlsgd\@l and stores the result in X3. Hidden by 3510b57cec5SDimitry Andric /// ADDIS_TLSGD_L_ADDR until after register assignment. 3520b57cec5SDimitry Andric ADDI_TLSGD_L, 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric /// %x3 = GET_TLS_ADDR %x3, Symbol - For the general-dynamic TLS 3550b57cec5SDimitry Andric /// model, produces a call to __tls_get_addr(sym\@tlsgd). Hidden by 3560b57cec5SDimitry Andric /// ADDIS_TLSGD_L_ADDR until after register assignment. 3570b57cec5SDimitry Andric GET_TLS_ADDR, 3580b57cec5SDimitry Andric 3595f757f3fSDimitry Andric /// %x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 3605f757f3fSDimitry Andric /// 32-bit AIX, produces a call to .__get_tpointer to retrieve the thread 3615f757f3fSDimitry Andric /// pointer. At the end of the call, the thread pointer is found in R3. 36206c3fb27SDimitry Andric GET_TPOINTER, 36306c3fb27SDimitry Andric 3640b57cec5SDimitry Andric /// G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that 3650b57cec5SDimitry Andric /// combines ADDI_TLSGD_L and GET_TLS_ADDR until expansion following 3660b57cec5SDimitry Andric /// register assignment. 3670b57cec5SDimitry Andric ADDI_TLSGD_L_ADDR, 3680b57cec5SDimitry Andric 369fe6060f1SDimitry Andric /// GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY 370fe6060f1SDimitry Andric /// G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY 371fe6060f1SDimitry Andric /// Op that combines two register copies of TOC entries 372fe6060f1SDimitry Andric /// (region handle into R3 and variable offset into R4) followed by a 373*0fca6ea1SDimitry Andric /// GET_TLS_ADDR node which will be expanded to a call to .__tls_get_addr. 374fe6060f1SDimitry Andric /// This node is used in 64-bit mode as well (in which case the result is 375fe6060f1SDimitry Andric /// G8RC and inputs are X3/X4). 376fe6060f1SDimitry Andric TLSGD_AIX, 377fe6060f1SDimitry Andric 378*0fca6ea1SDimitry Andric /// %x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model, 379*0fca6ea1SDimitry Andric /// produces a call to .__tls_get_mod(_$TLSML\@ml). 380*0fca6ea1SDimitry Andric GET_TLS_MOD_AIX, 381*0fca6ea1SDimitry Andric 382*0fca6ea1SDimitry Andric /// [GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle) 383*0fca6ea1SDimitry Andric /// Op that requires a single input of the module handle TOC entry in R3, 384*0fca6ea1SDimitry Andric /// and generates a GET_TLS_MOD_AIX node which will be expanded into a call 385*0fca6ea1SDimitry Andric /// to .__tls_get_mod. This node is used in both 32-bit and 64-bit modes. 386*0fca6ea1SDimitry Andric /// The only difference is the register class. 387*0fca6ea1SDimitry Andric TLSLD_AIX, 388*0fca6ea1SDimitry Andric 3890b57cec5SDimitry Andric /// G8RC = ADDIS_TLSLD_HA %x2, Symbol - For the local-dynamic TLS 3900b57cec5SDimitry Andric /// model, produces an ADDIS8 instruction that adds the GOT base 3910b57cec5SDimitry Andric /// register to sym\@got\@tlsld\@ha. 3920b57cec5SDimitry Andric ADDIS_TLSLD_HA, 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric /// %x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS 3950b57cec5SDimitry Andric /// model, produces an ADDI8 instruction that adds G8RReg to 3960b57cec5SDimitry Andric /// sym\@got\@tlsld\@l and stores the result in X3. Hidden by 3970b57cec5SDimitry Andric /// ADDIS_TLSLD_L_ADDR until after register assignment. 3980b57cec5SDimitry Andric ADDI_TLSLD_L, 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric /// %x3 = GET_TLSLD_ADDR %x3, Symbol - For the local-dynamic TLS 4010b57cec5SDimitry Andric /// model, produces a call to __tls_get_addr(sym\@tlsld). Hidden by 4020b57cec5SDimitry Andric /// ADDIS_TLSLD_L_ADDR until after register assignment. 4030b57cec5SDimitry Andric GET_TLSLD_ADDR, 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric /// G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that 4060b57cec5SDimitry Andric /// combines ADDI_TLSLD_L and GET_TLSLD_ADDR until expansion 4070b57cec5SDimitry Andric /// following register assignment. 4080b57cec5SDimitry Andric ADDI_TLSLD_L_ADDR, 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric /// G8RC = ADDIS_DTPREL_HA %x3, Symbol - For the local-dynamic TLS 4110b57cec5SDimitry Andric /// model, produces an ADDIS8 instruction that adds X3 to 4120b57cec5SDimitry Andric /// sym\@dtprel\@ha. 4130b57cec5SDimitry Andric ADDIS_DTPREL_HA, 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric /// G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS 4160b57cec5SDimitry Andric /// model, produces an ADDI8 instruction that adds G8RReg to 4170b57cec5SDimitry Andric /// sym\@got\@dtprel\@l. 4180b57cec5SDimitry Andric ADDI_DTPREL_L, 4190b57cec5SDimitry Andric 420e8d8bef9SDimitry Andric /// G8RC = PADDI_DTPREL %x3, Symbol - For the pc-rel based local-dynamic TLS 421e8d8bef9SDimitry Andric /// model, produces a PADDI8 instruction that adds X3 to sym\@dtprel. 422e8d8bef9SDimitry Andric PADDI_DTPREL, 423e8d8bef9SDimitry Andric 4240b57cec5SDimitry Andric /// VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded 4250b57cec5SDimitry Andric /// during instruction selection to optimize a BUILD_VECTOR into 4260b57cec5SDimitry Andric /// operations on splats. This is necessary to avoid losing these 4270b57cec5SDimitry Andric /// optimizations due to constant folding. 4280b57cec5SDimitry Andric VADD_SPLAT, 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric /// CHAIN = SC CHAIN, Imm128 - System call. The 7-bit unsigned 4310b57cec5SDimitry Andric /// operand identifies the operating system entry point. 4320b57cec5SDimitry Andric SC, 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric /// CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer. 4350b57cec5SDimitry Andric CLRBHRB, 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric /// GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch 4380b57cec5SDimitry Andric /// history rolling buffer entry. 4390b57cec5SDimitry Andric MFBHRBE, 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric /// CHAIN = RFEBB CHAIN, State - Return from event-based branch. 4420b57cec5SDimitry Andric RFEBB, 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric /// VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little 4450b57cec5SDimitry Andric /// endian. Maps to an xxswapd instruction that corrects an lxvd2x 4460b57cec5SDimitry Andric /// or stxvd2x instruction. The chain is necessary because the 4470b57cec5SDimitry Andric /// sequence replaces a load and needs to provide the same number 4480b57cec5SDimitry Andric /// of outputs. 4490b57cec5SDimitry Andric XXSWAPD, 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric /// An SDNode for swaps that are not associated with any loads/stores 4520b57cec5SDimitry Andric /// and thereby have no chain. 4530b57cec5SDimitry Andric SWAP_NO_CHAIN, 4540b57cec5SDimitry Andric 4558bcb0991SDimitry Andric /// FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or 4568bcb0991SDimitry Andric /// lower (IDX=1) half of v4f32 to v2f64. 4578bcb0991SDimitry Andric FP_EXTEND_HALF, 4580b57cec5SDimitry Andric 4595ffd83dbSDimitry Andric /// MAT_PCREL_ADDR = Materialize a PC Relative address. This can be done 4605ffd83dbSDimitry Andric /// either through an add like PADDI or through a PC Relative load like 4615ffd83dbSDimitry Andric /// PLD. 4625ffd83dbSDimitry Andric MAT_PCREL_ADDR, 4635ffd83dbSDimitry Andric 464e8d8bef9SDimitry Andric /// TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for 465e8d8bef9SDimitry Andric /// TLS global address when using dynamic access models. This can be done 466e8d8bef9SDimitry Andric /// through an add like PADDI. 467e8d8bef9SDimitry Andric TLS_DYNAMIC_MAT_PCREL_ADDR, 468e8d8bef9SDimitry Andric 469e8d8bef9SDimitry Andric /// TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address 470e8d8bef9SDimitry Andric /// when using local exec access models, and when prefixed instructions are 471e8d8bef9SDimitry Andric /// available. This is used with ADD_TLS to produce an add like PADDI. 472e8d8bef9SDimitry Andric TLS_LOCAL_EXEC_MAT_ADDR, 473e8d8bef9SDimitry Andric 474e8d8bef9SDimitry Andric /// ACC_BUILD = Build an accumulator register from 4 VSX registers. 475e8d8bef9SDimitry Andric ACC_BUILD, 476e8d8bef9SDimitry Andric 477e8d8bef9SDimitry Andric /// PAIR_BUILD = Build a vector pair register from 2 VSX registers. 478e8d8bef9SDimitry Andric PAIR_BUILD, 479e8d8bef9SDimitry Andric 480e8d8bef9SDimitry Andric /// EXTRACT_VSX_REG = Extract one of the underlying vsx registers of 481e8d8bef9SDimitry Andric /// an accumulator or pair register. This node is needed because 482e8d8bef9SDimitry Andric /// EXTRACT_SUBVECTOR expects the input and output vectors to have the same 483e8d8bef9SDimitry Andric /// element type. 484e8d8bef9SDimitry Andric EXTRACT_VSX_REG, 485e8d8bef9SDimitry Andric 486e8d8bef9SDimitry Andric /// XXMFACC = This corresponds to the xxmfacc instruction. 487e8d8bef9SDimitry Andric XXMFACC, 488e8d8bef9SDimitry Andric 489e8d8bef9SDimitry Andric // Constrained conversion from floating point to int 490e8d8bef9SDimitry Andric STRICT_FCTIDZ = ISD::FIRST_TARGET_STRICTFP_OPCODE, 491e8d8bef9SDimitry Andric STRICT_FCTIWZ, 492e8d8bef9SDimitry Andric STRICT_FCTIDUZ, 493e8d8bef9SDimitry Andric STRICT_FCTIWUZ, 494e8d8bef9SDimitry Andric 495e8d8bef9SDimitry Andric /// Constrained integer-to-floating-point conversion instructions. 496e8d8bef9SDimitry Andric STRICT_FCFID, 497e8d8bef9SDimitry Andric STRICT_FCFIDU, 498e8d8bef9SDimitry Andric STRICT_FCFIDS, 499e8d8bef9SDimitry Andric STRICT_FCFIDUS, 500e8d8bef9SDimitry Andric 501e8d8bef9SDimitry Andric /// Constrained floating point add in round-to-zero mode. 502e8d8bef9SDimitry Andric STRICT_FADDRTZ, 503e8d8bef9SDimitry Andric 504349cc55cSDimitry Andric // NOTE: The nodes below may require PC-Rel specific patterns if the 505349cc55cSDimitry Andric // address could be PC-Relative. When adding new nodes below, consider 506349cc55cSDimitry Andric // whether or not the address can be PC-Relative and add the corresponding 507349cc55cSDimitry Andric // PC-relative patterns and tests. 508349cc55cSDimitry Andric 5090b57cec5SDimitry Andric /// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a 5100b57cec5SDimitry Andric /// byte-swapping store instruction. It byte-swaps the low "Type" bits of 5110b57cec5SDimitry Andric /// the GPRC input, then stores it through Ptr. Type can be either i16 or 5120b57cec5SDimitry Andric /// i32. 5130b57cec5SDimitry Andric STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE, 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric /// GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a 5160b57cec5SDimitry Andric /// byte-swapping load instruction. It loads "Type" bits, byte swaps it, 5170b57cec5SDimitry Andric /// then puts it in the bottom bits of the GPRC. TYPE can be either i16 5180b57cec5SDimitry Andric /// or i32. 5190b57cec5SDimitry Andric LBRX, 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric /// STFIWX - The STFIWX instruction. The first operand is an input token 5220b57cec5SDimitry Andric /// chain, then an f64 value to store, then an address to store it to. 5230b57cec5SDimitry Andric STFIWX, 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric /// GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point 5260b57cec5SDimitry Andric /// load which sign-extends from a 32-bit integer value into the 5270b57cec5SDimitry Andric /// destination 64-bit register. 5280b57cec5SDimitry Andric LFIWAX, 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric /// GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point 5310b57cec5SDimitry Andric /// load which zero-extends from a 32-bit integer value into the 5320b57cec5SDimitry Andric /// destination 64-bit register. 5330b57cec5SDimitry Andric LFIWZX, 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric /// GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an 5360b57cec5SDimitry Andric /// integer smaller than 64 bits into a VSR. The integer is zero-extended. 5370b57cec5SDimitry Andric /// This can be used for converting loaded integers to floating point. 5380b57cec5SDimitry Andric LXSIZX, 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric /// STXSIX - The STXSI[bh]X instruction. The first operand is an input 5410b57cec5SDimitry Andric /// chain, then an f64 value to store, then an address to store it to, 5420b57cec5SDimitry Andric /// followed by a byte-width for the store. 5430b57cec5SDimitry Andric STXSIX, 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric /// VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian. 5460b57cec5SDimitry Andric /// Maps directly to an lxvd2x instruction that will be followed by 5470b57cec5SDimitry Andric /// an xxswapd. 5480b57cec5SDimitry Andric LXVD2X, 5490b57cec5SDimitry Andric 550e8d8bef9SDimitry Andric /// LXVRZX - Load VSX Vector Rightmost and Zero Extend 551e8d8bef9SDimitry Andric /// This node represents v1i128 BUILD_VECTOR of a zero extending load 552e8d8bef9SDimitry Andric /// instruction from <byte, halfword, word, or doubleword> to i128. 553e8d8bef9SDimitry Andric /// Allows utilization of the Load VSX Vector Rightmost Instructions. 554e8d8bef9SDimitry Andric LXVRZX, 555e8d8bef9SDimitry Andric 5568bcb0991SDimitry Andric /// VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian. 5578bcb0991SDimitry Andric /// Maps directly to one of lxvd2x/lxvw4x/lxvh8x/lxvb16x depending on 5588bcb0991SDimitry Andric /// the vector type to load vector in big-endian element order. 5598bcb0991SDimitry Andric LOAD_VEC_BE, 5608bcb0991SDimitry Andric 5610b57cec5SDimitry Andric /// VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a 5620b57cec5SDimitry Andric /// v2f32 value into the lower half of a VSR register. 5630b57cec5SDimitry Andric LD_VSX_LH, 5640b57cec5SDimitry Andric 5658bcb0991SDimitry Andric /// VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory 5668bcb0991SDimitry Andric /// instructions such as LXVDSX, LXVWSX. 5678bcb0991SDimitry Andric LD_SPLAT, 5688bcb0991SDimitry Andric 569349cc55cSDimitry Andric /// VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory 570349cc55cSDimitry Andric /// that zero-extends. 571349cc55cSDimitry Andric ZEXT_LD_SPLAT, 572349cc55cSDimitry Andric 573349cc55cSDimitry Andric /// VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory 574349cc55cSDimitry Andric /// that sign-extends. 575349cc55cSDimitry Andric SEXT_LD_SPLAT, 576349cc55cSDimitry Andric 5770b57cec5SDimitry Andric /// CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian. 5780b57cec5SDimitry Andric /// Maps directly to an stxvd2x instruction that will be preceded by 5790b57cec5SDimitry Andric /// an xxswapd. 5800b57cec5SDimitry Andric STXVD2X, 5810b57cec5SDimitry Andric 5828bcb0991SDimitry Andric /// CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian. 5838bcb0991SDimitry Andric /// Maps directly to one of stxvd2x/stxvw4x/stxvh8x/stxvb16x depending on 5848bcb0991SDimitry Andric /// the vector type to store vector in big-endian element order. 5858bcb0991SDimitry Andric STORE_VEC_BE, 5868bcb0991SDimitry Andric 5870b57cec5SDimitry Andric /// Store scalar integers from VSR. 5880b57cec5SDimitry Andric ST_VSR_SCAL_INT, 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric /// ATOMIC_CMP_SWAP - the exact same as the target-independent nodes 5910b57cec5SDimitry Andric /// except they ensure that the compare input is zero-extended for 5920b57cec5SDimitry Andric /// sub-word versions because the atomic loads zero-extend. 593480093f4SDimitry Andric ATOMIC_CMP_SWAP_8, 594480093f4SDimitry Andric ATOMIC_CMP_SWAP_16, 5950b57cec5SDimitry Andric 596bdd1243dSDimitry Andric /// CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr 597bdd1243dSDimitry Andric /// The store conditional instruction ST[BHWD]ARX that produces a glue 598bdd1243dSDimitry Andric /// result to attach it to a conditional branch. 599bdd1243dSDimitry Andric STORE_COND, 600bdd1243dSDimitry Andric 6010b57cec5SDimitry Andric /// GPRC = TOC_ENTRY GA, TOC 6020b57cec5SDimitry Andric /// Loads the entry for GA from the TOC, where the TOC base is given by 6030b57cec5SDimitry Andric /// the last operand. 6040b57cec5SDimitry Andric TOC_ENTRY 6050b57cec5SDimitry Andric }; 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric } // end namespace PPCISD 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andric /// Define some predicates that are used for node matching. 6100b57cec5SDimitry Andric namespace PPC { 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a 6130b57cec5SDimitry Andric /// VPKUHUM instruction. 6140b57cec5SDimitry Andric bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, 6150b57cec5SDimitry Andric SelectionDAG &DAG); 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a 6180b57cec5SDimitry Andric /// VPKUWUM instruction. 6190b57cec5SDimitry Andric bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, 6200b57cec5SDimitry Andric SelectionDAG &DAG); 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric /// isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a 6230b57cec5SDimitry Andric /// VPKUDUM instruction. 6240b57cec5SDimitry Andric bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, 6250b57cec5SDimitry Andric SelectionDAG &DAG); 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for 6280b57cec5SDimitry Andric /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes). 6290b57cec5SDimitry Andric bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, 6300b57cec5SDimitry Andric unsigned ShuffleKind, SelectionDAG &DAG); 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for 6330b57cec5SDimitry Andric /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes). 6340b57cec5SDimitry Andric bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, 6350b57cec5SDimitry Andric unsigned ShuffleKind, SelectionDAG &DAG); 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric /// isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for 6380b57cec5SDimitry Andric /// a VMRGEW or VMRGOW instruction 6390b57cec5SDimitry Andric bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, 6400b57cec5SDimitry Andric unsigned ShuffleKind, SelectionDAG &DAG); 6410b57cec5SDimitry Andric /// isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable 6420b57cec5SDimitry Andric /// for a XXSLDWI instruction. 6430b57cec5SDimitry Andric bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, 6440b57cec5SDimitry Andric bool &Swap, bool IsLE); 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric /// isXXBRHShuffleMask - Return true if this is a shuffle mask suitable 6470b57cec5SDimitry Andric /// for a XXBRH instruction. 6480b57cec5SDimitry Andric bool isXXBRHShuffleMask(ShuffleVectorSDNode *N); 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric /// isXXBRWShuffleMask - Return true if this is a shuffle mask suitable 6510b57cec5SDimitry Andric /// for a XXBRW instruction. 6520b57cec5SDimitry Andric bool isXXBRWShuffleMask(ShuffleVectorSDNode *N); 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric /// isXXBRDShuffleMask - Return true if this is a shuffle mask suitable 6550b57cec5SDimitry Andric /// for a XXBRD instruction. 6560b57cec5SDimitry Andric bool isXXBRDShuffleMask(ShuffleVectorSDNode *N); 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric /// isXXBRQShuffleMask - Return true if this is a shuffle mask suitable 6590b57cec5SDimitry Andric /// for a XXBRQ instruction. 6600b57cec5SDimitry Andric bool isXXBRQShuffleMask(ShuffleVectorSDNode *N); 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric /// isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable 6630b57cec5SDimitry Andric /// for a XXPERMDI instruction. 6640b57cec5SDimitry Andric bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, 6650b57cec5SDimitry Andric bool &Swap, bool IsLE); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the 6680b57cec5SDimitry Andric /// shift amount, otherwise return -1. 6690b57cec5SDimitry Andric int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, 6700b57cec5SDimitry Andric SelectionDAG &DAG); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand 6730b57cec5SDimitry Andric /// specifies a splat of a single element that is suitable for input to 6740b57cec5SDimitry Andric /// VSPLTB/VSPLTH/VSPLTW. 6750b57cec5SDimitry Andric bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize); 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric /// isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by 6780b57cec5SDimitry Andric /// the XXINSERTW instruction introduced in ISA 3.0. This is essentially any 6790b57cec5SDimitry Andric /// shuffle of v4f32/v4i32 vectors that just inserts one element from one 6800b57cec5SDimitry Andric /// vector into the other. This function will also set a couple of 6810b57cec5SDimitry Andric /// output parameters for how much the source vector needs to be shifted and 6820b57cec5SDimitry Andric /// what byte number needs to be specified for the instruction to put the 6830b57cec5SDimitry Andric /// element in the desired location of the target vector. 6840b57cec5SDimitry Andric bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, 6850b57cec5SDimitry Andric unsigned &InsertAtByte, bool &Swap, bool IsLE); 6860b57cec5SDimitry Andric 6878bcb0991SDimitry Andric /// getSplatIdxForPPCMnemonics - Return the splat index as a value that is 6888bcb0991SDimitry Andric /// appropriate for PPC mnemonics (which have a big endian bias - namely 6898bcb0991SDimitry Andric /// elements are counted from the left of the vector register). 6908bcb0991SDimitry Andric unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, 6918bcb0991SDimitry Andric SelectionDAG &DAG); 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric /// get_VSPLTI_elt - If this is a build_vector of constants which can be 6940b57cec5SDimitry Andric /// formed by using a vspltis[bhw] instruction of the specified element 6950b57cec5SDimitry Andric /// size, return the constant being splatted. The ByteSize field indicates 6960b57cec5SDimitry Andric /// the number of bytes of each element [124] -> [bhw]. 6970b57cec5SDimitry Andric SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG); 6980b57cec5SDimitry Andric 699fe6060f1SDimitry Andric // Flags for computing the optimal addressing mode for loads and stores. 700fe6060f1SDimitry Andric enum MemOpFlags { 701fe6060f1SDimitry Andric MOF_None = 0, 702fe6060f1SDimitry Andric 703fe6060f1SDimitry Andric // Extension mode for integer loads. 704fe6060f1SDimitry Andric MOF_SExt = 1, 705fe6060f1SDimitry Andric MOF_ZExt = 1 << 1, 706fe6060f1SDimitry Andric MOF_NoExt = 1 << 2, 707fe6060f1SDimitry Andric 708fe6060f1SDimitry Andric // Address computation flags. 709fe6060f1SDimitry Andric MOF_NotAddNorCst = 1 << 5, // Not const. or sum of ptr and scalar. 710fe6060f1SDimitry Andric MOF_RPlusSImm16 = 1 << 6, // Reg plus signed 16-bit constant. 711fe6060f1SDimitry Andric MOF_RPlusLo = 1 << 7, // Reg plus signed 16-bit relocation 712fe6060f1SDimitry Andric MOF_RPlusSImm16Mult4 = 1 << 8, // Reg plus 16-bit signed multiple of 4. 713fe6060f1SDimitry Andric MOF_RPlusSImm16Mult16 = 1 << 9, // Reg plus 16-bit signed multiple of 16. 714fe6060f1SDimitry Andric MOF_RPlusSImm34 = 1 << 10, // Reg plus 34-bit signed constant. 715fe6060f1SDimitry Andric MOF_RPlusR = 1 << 11, // Sum of two variables. 716fe6060f1SDimitry Andric MOF_PCRel = 1 << 12, // PC-Relative relocation. 717fe6060f1SDimitry Andric MOF_AddrIsSImm32 = 1 << 13, // A simple 32-bit constant. 718fe6060f1SDimitry Andric 719fe6060f1SDimitry Andric // The in-memory type. 720fe6060f1SDimitry Andric MOF_SubWordInt = 1 << 15, 721fe6060f1SDimitry Andric MOF_WordInt = 1 << 16, 722fe6060f1SDimitry Andric MOF_DoubleWordInt = 1 << 17, 723fe6060f1SDimitry Andric MOF_ScalarFloat = 1 << 18, // Scalar single or double precision. 724fe6060f1SDimitry Andric MOF_Vector = 1 << 19, // Vector types and quad precision scalars. 725fe6060f1SDimitry Andric MOF_Vector256 = 1 << 20, 726fe6060f1SDimitry Andric 727fe6060f1SDimitry Andric // Subtarget features. 728fe6060f1SDimitry Andric MOF_SubtargetBeforeP9 = 1 << 22, 729fe6060f1SDimitry Andric MOF_SubtargetP9 = 1 << 23, 730fe6060f1SDimitry Andric MOF_SubtargetP10 = 1 << 24, 731fe6060f1SDimitry Andric MOF_SubtargetSPE = 1 << 25 732fe6060f1SDimitry Andric }; 733fe6060f1SDimitry Andric 734fe6060f1SDimitry Andric // The addressing modes for loads and stores. 735fe6060f1SDimitry Andric enum AddrMode { 736fe6060f1SDimitry Andric AM_None, 737fe6060f1SDimitry Andric AM_DForm, 738fe6060f1SDimitry Andric AM_DSForm, 739fe6060f1SDimitry Andric AM_DQForm, 740349cc55cSDimitry Andric AM_PrefixDForm, 741fe6060f1SDimitry Andric AM_XForm, 742349cc55cSDimitry Andric AM_PCRel 743fe6060f1SDimitry Andric }; 7440b57cec5SDimitry Andric } // end namespace PPC 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric class PPCTargetLowering : public TargetLowering { 7470b57cec5SDimitry Andric const PPCSubtarget &Subtarget; 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric public: 7500b57cec5SDimitry Andric explicit PPCTargetLowering(const PPCTargetMachine &TM, 7510b57cec5SDimitry Andric const PPCSubtarget &STI); 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric /// getTargetNodeName() - This method returns the name of a target specific 7540b57cec5SDimitry Andric /// DAG node. 7550b57cec5SDimitry Andric const char *getTargetNodeName(unsigned Opcode) const override; 7560b57cec5SDimitry Andric isSelectSupported(SelectSupportKind Kind)7570b57cec5SDimitry Andric bool isSelectSupported(SelectSupportKind Kind) const override { 7580b57cec5SDimitry Andric // PowerPC does not support scalar condition selects on vectors. 7590b57cec5SDimitry Andric return (Kind != SelectSupportKind::ScalarCondVectorVal); 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric /// getPreferredVectorAction - The code we generate when vector types are 7630b57cec5SDimitry Andric /// legalized by promoting the integer element type is often much worse 7640b57cec5SDimitry Andric /// than code we generate if we widen the type for applicable vector types. 7650b57cec5SDimitry Andric /// The issue with promoting is that the vector is scalaraized, individual 7660b57cec5SDimitry Andric /// elements promoted and then the vector is rebuilt. So say we load a pair 7670b57cec5SDimitry Andric /// of v4i8's and shuffle them. This will turn into a mess of 8 extending 7680b57cec5SDimitry Andric /// loads, moves back into VSR's (or memory ops if we don't have moves) and 7690b57cec5SDimitry Andric /// then the VPERM for the shuffle. All in all a very slow sequence. getPreferredVectorAction(MVT VT)7700b57cec5SDimitry Andric TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) 7710b57cec5SDimitry Andric const override { 772d781ede6SDimitry Andric // Default handling for scalable and single-element vectors. 773d781ede6SDimitry Andric if (VT.isScalableVector() || VT.getVectorNumElements() == 1) 774d781ede6SDimitry Andric return TargetLoweringBase::getPreferredVectorAction(VT); 775d781ede6SDimitry Andric 776d781ede6SDimitry Andric // Split and promote vNi1 vectors so we don't produce v256i1/v512i1 777d781ede6SDimitry Andric // types as those are only for MMA instructions. 778d781ede6SDimitry Andric if (VT.getScalarSizeInBits() == 1 && VT.getSizeInBits() > 16) 779d781ede6SDimitry Andric return TypeSplitVector; 780d781ede6SDimitry Andric if (VT.getScalarSizeInBits() == 1) 781d781ede6SDimitry Andric return TypePromoteInteger; 782d781ede6SDimitry Andric 783d781ede6SDimitry Andric // Widen vectors that have reasonably sized elements. 784d781ede6SDimitry Andric if (VT.getScalarSizeInBits() % 8 == 0) 7850b57cec5SDimitry Andric return TypeWidenVector; 7860b57cec5SDimitry Andric return TargetLoweringBase::getPreferredVectorAction(VT); 7870b57cec5SDimitry Andric } 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric bool useSoftFloat() const override; 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric bool hasSPE() const; 7920b57cec5SDimitry Andric getScalarShiftAmountTy(const DataLayout &,EVT)7930b57cec5SDimitry Andric MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { 7940b57cec5SDimitry Andric return MVT::i32; 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric isCheapToSpeculateCttz(Type * Ty)797bdd1243dSDimitry Andric bool isCheapToSpeculateCttz(Type *Ty) const override { 7980b57cec5SDimitry Andric return true; 7990b57cec5SDimitry Andric } 8000b57cec5SDimitry Andric isCheapToSpeculateCtlz(Type * Ty)801bdd1243dSDimitry Andric bool isCheapToSpeculateCtlz(Type *Ty) const override { 8020b57cec5SDimitry Andric return true; 8030b57cec5SDimitry Andric } 8040b57cec5SDimitry Andric 8055f757f3fSDimitry Andric bool 8065f757f3fSDimitry Andric shallExtractConstSplatVectorElementToStore(Type *VectorTy, 8075f757f3fSDimitry Andric unsigned ElemSizeInBits, 8085f757f3fSDimitry Andric unsigned &Index) const override; 8095f757f3fSDimitry Andric isCtlzFast()8100b57cec5SDimitry Andric bool isCtlzFast() const override { 8110b57cec5SDimitry Andric return true; 8120b57cec5SDimitry Andric } 8130b57cec5SDimitry Andric isEqualityCmpFoldedWithSignedCmp()814480093f4SDimitry Andric bool isEqualityCmpFoldedWithSignedCmp() const override { 815480093f4SDimitry Andric return false; 816480093f4SDimitry Andric } 817480093f4SDimitry Andric hasAndNotCompare(SDValue)8180b57cec5SDimitry Andric bool hasAndNotCompare(SDValue) const override { 8190b57cec5SDimitry Andric return true; 8200b57cec5SDimitry Andric } 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric bool preferIncOfAddToSubOfNot(EVT VT) const override; 8230b57cec5SDimitry Andric convertSetCCLogicToBitwiseLogic(EVT VT)8240b57cec5SDimitry Andric bool convertSetCCLogicToBitwiseLogic(EVT VT) const override { 8250b57cec5SDimitry Andric return VT.isScalarInteger(); 8260b57cec5SDimitry Andric } 8270b57cec5SDimitry Andric 8285ffd83dbSDimitry Andric SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, 8295ffd83dbSDimitry Andric bool OptForSize, NegatibleCost &Cost, 8305ffd83dbSDimitry Andric unsigned Depth = 0) const override; 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric /// getSetCCResultType - Return the ISD::SETCC ValueType 8330b57cec5SDimitry Andric EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, 8340b57cec5SDimitry Andric EVT VT) const override; 8350b57cec5SDimitry Andric 836fe6060f1SDimitry Andric /// Return true if target always benefits from combining into FMA for a 8370b57cec5SDimitry Andric /// given value type. This must typically return false on targets where FMA 8380b57cec5SDimitry Andric /// takes more cycles to execute than FADD. 8390b57cec5SDimitry Andric bool enableAggressiveFMAFusion(EVT VT) const override; 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric /// getPreIndexedAddressParts - returns true by value, base pointer and 8420b57cec5SDimitry Andric /// offset pointer and addressing mode by reference if the node's address 8430b57cec5SDimitry Andric /// can be legally represented as pre-indexed load / store address. 8440b57cec5SDimitry Andric bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, 8450b57cec5SDimitry Andric SDValue &Offset, 8460b57cec5SDimitry Andric ISD::MemIndexedMode &AM, 8470b57cec5SDimitry Andric SelectionDAG &DAG) const override; 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric /// SelectAddressEVXRegReg - Given the specified addressed, check to see if 8500b57cec5SDimitry Andric /// it can be more efficiently represented as [r+imm]. 8510b57cec5SDimitry Andric bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, 8520b57cec5SDimitry Andric SelectionDAG &DAG) const; 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric /// SelectAddressRegReg - Given the specified addressed, check to see if it 8550b57cec5SDimitry Andric /// can be more efficiently represented as [r+imm]. If \p EncodingAlignment 8560b57cec5SDimitry Andric /// is non-zero, only accept displacement which is not suitable for [r+imm]. 8570b57cec5SDimitry Andric /// Returns false if it can be represented by [r+imm], which are preferred. 8580b57cec5SDimitry Andric bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, 8590b57cec5SDimitry Andric SelectionDAG &DAG, 860bdd1243dSDimitry Andric MaybeAlign EncodingAlignment = std::nullopt) const; 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric /// SelectAddressRegImm - Returns true if the address N can be represented 8630b57cec5SDimitry Andric /// by a base register plus a signed 16-bit displacement [r+imm], and if it 8640b57cec5SDimitry Andric /// is not better represented as reg+reg. If \p EncodingAlignment is 8650b57cec5SDimitry Andric /// non-zero, only accept displacements suitable for instruction encoding 8660b57cec5SDimitry Andric /// requirement, i.e. multiples of 4 for DS form. 8670b57cec5SDimitry Andric bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, 8680b57cec5SDimitry Andric SelectionDAG &DAG, 8695ffd83dbSDimitry Andric MaybeAlign EncodingAlignment) const; 870e8d8bef9SDimitry Andric bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, 871e8d8bef9SDimitry Andric SelectionDAG &DAG) const; 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric /// SelectAddressRegRegOnly - Given the specified addressed, force it to be 8740b57cec5SDimitry Andric /// represented as an indexed [r+r] operation. 8750b57cec5SDimitry Andric bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, 8760b57cec5SDimitry Andric SelectionDAG &DAG) const; 8770b57cec5SDimitry Andric 8785ffd83dbSDimitry Andric /// SelectAddressPCRel - Represent the specified address as pc relative to 8795ffd83dbSDimitry Andric /// be represented as [pc+imm] 8805ffd83dbSDimitry Andric bool SelectAddressPCRel(SDValue N, SDValue &Base) const; 8815ffd83dbSDimitry Andric 8820b57cec5SDimitry Andric Sched::Preference getSchedulingPreference(SDNode *N) const override; 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric /// LowerOperation - Provide custom lowering hooks for some operations. 8850b57cec5SDimitry Andric /// 8860b57cec5SDimitry Andric SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 8870b57cec5SDimitry Andric 8880b57cec5SDimitry Andric /// ReplaceNodeResults - Replace the results of node with an illegal result 8890b57cec5SDimitry Andric /// type with new values built out of custom code. 8900b57cec5SDimitry Andric /// 8910b57cec5SDimitry Andric void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, 8920b57cec5SDimitry Andric SelectionDAG &DAG) const override; 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const; 8950b57cec5SDimitry Andric SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const; 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, 9000b57cec5SDimitry Andric SmallVectorImpl<SDNode *> &Created) const override; 9010b57cec5SDimitry Andric 902480093f4SDimitry Andric Register getRegisterByName(const char* RegName, LLT VT, 9038bcb0991SDimitry Andric const MachineFunction &MF) const override; 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric void computeKnownBitsForTargetNode(const SDValue Op, 9060b57cec5SDimitry Andric KnownBits &Known, 9070b57cec5SDimitry Andric const APInt &DemandedElts, 9080b57cec5SDimitry Andric const SelectionDAG &DAG, 9090b57cec5SDimitry Andric unsigned Depth = 0) const override; 9100b57cec5SDimitry Andric 9118bcb0991SDimitry Andric Align getPrefLoopAlignment(MachineLoop *ML) const override; 9120b57cec5SDimitry Andric shouldInsertFencesForAtomic(const Instruction * I)9130b57cec5SDimitry Andric bool shouldInsertFencesForAtomic(const Instruction *I) const override { 9140b57cec5SDimitry Andric return true; 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric 917fe6060f1SDimitry Andric Instruction *emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, 9180b57cec5SDimitry Andric AtomicOrdering Ord) const override; 919fe6060f1SDimitry Andric Instruction *emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, 920fe6060f1SDimitry Andric AtomicOrdering Ord) const override; 921fe6060f1SDimitry Andric 92281ad6265SDimitry Andric bool shouldInlineQuadwordAtomics() const; 92381ad6265SDimitry Andric 924fe6060f1SDimitry Andric TargetLowering::AtomicExpansionKind 925fe6060f1SDimitry Andric shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override; 926fe6060f1SDimitry Andric 927fe6060f1SDimitry Andric TargetLowering::AtomicExpansionKind 928fe6060f1SDimitry Andric shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override; 929fe6060f1SDimitry Andric 930fe6060f1SDimitry Andric Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, 931fe6060f1SDimitry Andric AtomicRMWInst *AI, Value *AlignedAddr, 932fe6060f1SDimitry Andric Value *Incr, Value *Mask, 933fe6060f1SDimitry Andric Value *ShiftAmt, 934fe6060f1SDimitry Andric AtomicOrdering Ord) const override; 935fe6060f1SDimitry Andric Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, 936fe6060f1SDimitry Andric AtomicCmpXchgInst *CI, 937fe6060f1SDimitry Andric Value *AlignedAddr, Value *CmpVal, 938fe6060f1SDimitry Andric Value *NewVal, Value *Mask, 9390b57cec5SDimitry Andric AtomicOrdering Ord) const override; 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric MachineBasicBlock * 9420b57cec5SDimitry Andric EmitInstrWithCustomInserter(MachineInstr &MI, 9430b57cec5SDimitry Andric MachineBasicBlock *MBB) const override; 9440b57cec5SDimitry Andric MachineBasicBlock *EmitAtomicBinary(MachineInstr &MI, 9450b57cec5SDimitry Andric MachineBasicBlock *MBB, 9460b57cec5SDimitry Andric unsigned AtomicSize, 9470b57cec5SDimitry Andric unsigned BinOpcode, 9480b57cec5SDimitry Andric unsigned CmpOpcode = 0, 9490b57cec5SDimitry Andric unsigned CmpPred = 0) const; 9500b57cec5SDimitry Andric MachineBasicBlock *EmitPartwordAtomicBinary(MachineInstr &MI, 9510b57cec5SDimitry Andric MachineBasicBlock *MBB, 9520b57cec5SDimitry Andric bool is8bit, 9530b57cec5SDimitry Andric unsigned Opcode, 9540b57cec5SDimitry Andric unsigned CmpOpcode = 0, 9550b57cec5SDimitry Andric unsigned CmpPred = 0) const; 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI, 9580b57cec5SDimitry Andric MachineBasicBlock *MBB) const; 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI, 9610b57cec5SDimitry Andric MachineBasicBlock *MBB) const; 9620b57cec5SDimitry Andric 9635ffd83dbSDimitry Andric MachineBasicBlock *emitProbedAlloca(MachineInstr &MI, 9645ffd83dbSDimitry Andric MachineBasicBlock *MBB) const; 9655ffd83dbSDimitry Andric 966bdd1243dSDimitry Andric bool hasInlineStackProbe(const MachineFunction &MF) const override; 9675ffd83dbSDimitry Andric 968bdd1243dSDimitry Andric unsigned getStackProbeSize(const MachineFunction &MF) const; 9695ffd83dbSDimitry Andric 9700b57cec5SDimitry Andric ConstraintType getConstraintType(StringRef Constraint) const override; 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric /// Examine constraint string and operand type and determine a weight value. 9730b57cec5SDimitry Andric /// The operand object must already have been set up with the operand type. 9740b57cec5SDimitry Andric ConstraintWeight getSingleConstraintMatchWeight( 9750b57cec5SDimitry Andric AsmOperandInfo &info, const char *constraint) const override; 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric std::pair<unsigned, const TargetRegisterClass *> 9780b57cec5SDimitry Andric getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 9790b57cec5SDimitry Andric StringRef Constraint, MVT VT) const override; 9800b57cec5SDimitry Andric 9810b57cec5SDimitry Andric /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate 9820b57cec5SDimitry Andric /// function arguments in the caller parameter area. This is the actual 9830b57cec5SDimitry Andric /// alignment, not its logarithm. 984349cc55cSDimitry Andric uint64_t getByValTypeAlignment(Type *Ty, 9850b57cec5SDimitry Andric const DataLayout &DL) const override; 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops 9880b57cec5SDimitry Andric /// vector. If it is invalid, don't add anything to Ops. 9895f757f3fSDimitry Andric void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, 9900b57cec5SDimitry Andric std::vector<SDValue> &Ops, 9910b57cec5SDimitry Andric SelectionDAG &DAG) const override; 9920b57cec5SDimitry Andric 9935f757f3fSDimitry Andric InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode)9940b57cec5SDimitry Andric getInlineAsmMemConstraint(StringRef ConstraintCode) const override { 9950b57cec5SDimitry Andric if (ConstraintCode == "es") 9965f757f3fSDimitry Andric return InlineAsm::ConstraintCode::es; 9970b57cec5SDimitry Andric else if (ConstraintCode == "Q") 9985f757f3fSDimitry Andric return InlineAsm::ConstraintCode::Q; 9990b57cec5SDimitry Andric else if (ConstraintCode == "Z") 10005f757f3fSDimitry Andric return InlineAsm::ConstraintCode::Z; 10010b57cec5SDimitry Andric else if (ConstraintCode == "Zy") 10025f757f3fSDimitry Andric return InlineAsm::ConstraintCode::Zy; 10030b57cec5SDimitry Andric return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); 10040b57cec5SDimitry Andric } 10050b57cec5SDimitry Andric 1006bdd1243dSDimitry Andric void CollectTargetIntrinsicOperands(const CallInst &I, 1007bdd1243dSDimitry Andric SmallVectorImpl<SDValue> &Ops, 1008bdd1243dSDimitry Andric SelectionDAG &DAG) const override; 1009bdd1243dSDimitry Andric 10100b57cec5SDimitry Andric /// isLegalAddressingMode - Return true if the addressing mode represented 10110b57cec5SDimitry Andric /// by AM is legal for this target, for a load/store of the specified type. 10120b57cec5SDimitry Andric bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, 10130b57cec5SDimitry Andric Type *Ty, unsigned AS, 10140b57cec5SDimitry Andric Instruction *I = nullptr) const override; 10150b57cec5SDimitry Andric 10160b57cec5SDimitry Andric /// isLegalICmpImmediate - Return true if the specified immediate is legal 10170b57cec5SDimitry Andric /// icmp immediate, that is the target has icmp instructions which can 10180b57cec5SDimitry Andric /// compare a register against the immediate without having to materialize 10190b57cec5SDimitry Andric /// the immediate into a register. 10200b57cec5SDimitry Andric bool isLegalICmpImmediate(int64_t Imm) const override; 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric /// isLegalAddImmediate - Return true if the specified immediate is legal 10230b57cec5SDimitry Andric /// add immediate, that is the target has add instructions which can 10240b57cec5SDimitry Andric /// add a register and the immediate without having to materialize 10250b57cec5SDimitry Andric /// the immediate into a register. 10260b57cec5SDimitry Andric bool isLegalAddImmediate(int64_t Imm) const override; 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andric /// isTruncateFree - Return true if it's free to truncate a value of 10290b57cec5SDimitry Andric /// type Ty1 to type Ty2. e.g. On PPC it's free to truncate a i64 value in 10300b57cec5SDimitry Andric /// register X1 to i32 by referencing its sub-register R1. 10310b57cec5SDimitry Andric bool isTruncateFree(Type *Ty1, Type *Ty2) const override; 10320b57cec5SDimitry Andric bool isTruncateFree(EVT VT1, EVT VT2) const override; 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric bool isZExtFree(SDValue Val, EVT VT2) const override; 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric bool isFPExtFree(EVT DestVT, EVT SrcVT) const override; 10370b57cec5SDimitry Andric 10380b57cec5SDimitry Andric /// Returns true if it is beneficial to convert a load of a constant 10390b57cec5SDimitry Andric /// to just the constant itself. 10400b57cec5SDimitry Andric bool shouldConvertConstantLoadToIntImm(const APInt &Imm, 10410b57cec5SDimitry Andric Type *Ty) const override; 10420b57cec5SDimitry Andric convertSelectOfConstantsToMath(EVT VT)10430b57cec5SDimitry Andric bool convertSelectOfConstantsToMath(EVT VT) const override { 10440b57cec5SDimitry Andric return true; 10450b57cec5SDimitry Andric } 10460b57cec5SDimitry Andric 1047e8d8bef9SDimitry Andric bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 1048e8d8bef9SDimitry Andric SDValue C) const override; 1049e8d8bef9SDimitry Andric isDesirableToTransformToIntegerOp(unsigned Opc,EVT VT)10508bcb0991SDimitry Andric bool isDesirableToTransformToIntegerOp(unsigned Opc, 10518bcb0991SDimitry Andric EVT VT) const override { 10528bcb0991SDimitry Andric // Only handle float load/store pair because float(fpr) load/store 10538bcb0991SDimitry Andric // instruction has more cycles than integer(gpr) load/store in PPC. 10548bcb0991SDimitry Andric if (Opc != ISD::LOAD && Opc != ISD::STORE) 10558bcb0991SDimitry Andric return false; 10568bcb0991SDimitry Andric if (VT != MVT::f32 && VT != MVT::f64) 10578bcb0991SDimitry Andric return false; 10588bcb0991SDimitry Andric 10598bcb0991SDimitry Andric return true; 10608bcb0991SDimitry Andric } 10618bcb0991SDimitry Andric 10620b57cec5SDimitry Andric // Returns true if the address of the global is stored in TOC entry. 10630b57cec5SDimitry Andric bool isAccessedAsGotIndirect(SDValue N) const; 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric bool getTgtMemIntrinsic(IntrinsicInfo &Info, 10680b57cec5SDimitry Andric const CallInst &I, 10690b57cec5SDimitry Andric MachineFunction &MF, 10700b57cec5SDimitry Andric unsigned Intrinsic) const override; 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric /// It returns EVT::Other if the type should be determined using generic 10730b57cec5SDimitry Andric /// target-independent logic. 10745ffd83dbSDimitry Andric EVT getOptimalMemOpType(const MemOp &Op, 10750b57cec5SDimitry Andric const AttributeList &FuncAttributes) const override; 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric /// Is unaligned memory access allowed for the given type, and is it fast 10780b57cec5SDimitry Andric /// relative to software emulation. 10790b57cec5SDimitry Andric bool allowsMisalignedMemoryAccesses( 1080fe6060f1SDimitry Andric EVT VT, unsigned AddrSpace, Align Alignment = Align(1), 10810b57cec5SDimitry Andric MachineMemOperand::Flags Flags = MachineMemOperand::MONone, 1082bdd1243dSDimitry Andric unsigned *Fast = nullptr) const override; 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric /// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster 10850b57cec5SDimitry Andric /// than a pair of fmul and fadd instructions. fmuladd intrinsics will be 10860b57cec5SDimitry Andric /// expanded to FMAs when this method returns true, otherwise fmuladd is 10870b57cec5SDimitry Andric /// expanded to fmul + fadd. 1088480093f4SDimitry Andric bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, 1089480093f4SDimitry Andric EVT VT) const override; 10900b57cec5SDimitry Andric 10915ffd83dbSDimitry Andric bool isFMAFasterThanFMulAndFAdd(const Function &F, Type *Ty) const override; 10925ffd83dbSDimitry Andric 10935ffd83dbSDimitry Andric /// isProfitableToHoist - Check if it is profitable to hoist instruction 10945ffd83dbSDimitry Andric /// \p I to its dominator block. 10955ffd83dbSDimitry Andric /// For example, it is not profitable if \p I and it's only user can form a 10965ffd83dbSDimitry Andric /// FMA instruction, because Powerpc prefers FMADD. 10975ffd83dbSDimitry Andric bool isProfitableToHoist(Instruction *I) const override; 10985ffd83dbSDimitry Andric 10990b57cec5SDimitry Andric const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override; 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric // Should we expand the build vector with shuffles? 11020b57cec5SDimitry Andric bool 11030b57cec5SDimitry Andric shouldExpandBuildVectorWithShuffles(EVT VT, 11040b57cec5SDimitry Andric unsigned DefinedValues) const override; 11050b57cec5SDimitry Andric 1106d409305fSDimitry Andric // Keep the zero-extensions for arguments to libcalls. shouldKeepZExtForFP16Conv()1107d409305fSDimitry Andric bool shouldKeepZExtForFP16Conv() const override { return true; } 1108d409305fSDimitry Andric 11090b57cec5SDimitry Andric /// createFastISel - This method returns a target-specific FastISel object, 11100b57cec5SDimitry Andric /// or null if the target does not support "fast" instruction selection. 11110b57cec5SDimitry Andric FastISel *createFastISel(FunctionLoweringInfo &FuncInfo, 11120b57cec5SDimitry Andric const TargetLibraryInfo *LibInfo) const override; 11130b57cec5SDimitry Andric 11140b57cec5SDimitry Andric /// Returns true if an argument of type Ty needs to be passed in a 11150b57cec5SDimitry Andric /// contiguous block of registers in calling convention CallConv. functionArgumentNeedsConsecutiveRegisters(Type * Ty,CallingConv::ID CallConv,bool isVarArg,const DataLayout & DL)11160b57cec5SDimitry Andric bool functionArgumentNeedsConsecutiveRegisters( 1117fe6060f1SDimitry Andric Type *Ty, CallingConv::ID CallConv, bool isVarArg, 1118fe6060f1SDimitry Andric const DataLayout &DL) const override { 11190b57cec5SDimitry Andric // We support any array type as "consecutive" block in the parameter 11200b57cec5SDimitry Andric // save area. The element type defines the alignment requirement and 11210b57cec5SDimitry Andric // whether the argument should go in GPRs, FPRs, or VRs if available. 11220b57cec5SDimitry Andric // 11230b57cec5SDimitry Andric // Note that clang uses this capability both to implement the ELFv2 11240b57cec5SDimitry Andric // homogeneous float/vector aggregate ABI, and to avoid having to use 11250b57cec5SDimitry Andric // "byval" when passing aggregates that might fully fit in registers. 11260b57cec5SDimitry Andric return Ty->isArrayTy(); 11270b57cec5SDimitry Andric } 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric /// If a physical register, this returns the register that receives the 11300b57cec5SDimitry Andric /// exception address on entry to an EH pad. 11315ffd83dbSDimitry Andric Register 11320b57cec5SDimitry Andric getExceptionPointerRegister(const Constant *PersonalityFn) const override; 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric /// If a physical register, this returns the register that receives the 11350b57cec5SDimitry Andric /// exception typeid on entry to a landing pad. 11365ffd83dbSDimitry Andric Register 11370b57cec5SDimitry Andric getExceptionSelectorRegister(const Constant *PersonalityFn) const override; 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andric /// Override to support customized stack guard loading. 11400b57cec5SDimitry Andric bool useLoadStackGuardNode() const override; 11410b57cec5SDimitry Andric void insertSSPDeclarations(Module &M) const override; 1142fe6060f1SDimitry Andric Value *getSDagStackGuard(const Module &M) const override; 11430b57cec5SDimitry Andric 11440b57cec5SDimitry Andric bool isFPImmLegal(const APFloat &Imm, EVT VT, 11450b57cec5SDimitry Andric bool ForCodeSize) const override; 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric unsigned getJumpTableEncoding() const override; 11480b57cec5SDimitry Andric bool isJumpTableRelative() const override; 11490b57cec5SDimitry Andric SDValue getPICJumpTableRelocBase(SDValue Table, 11500b57cec5SDimitry Andric SelectionDAG &DAG) const override; 11510b57cec5SDimitry Andric const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF, 11520b57cec5SDimitry Andric unsigned JTI, 11530b57cec5SDimitry Andric MCContext &Ctx) const override; 11540b57cec5SDimitry Andric 1155fe6060f1SDimitry Andric /// SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), 1156fe6060f1SDimitry Andric /// compute the address flags of the node, get the optimal address mode 1157fe6060f1SDimitry Andric /// based on the flags, and set the Base and Disp based on the address mode. 1158fe6060f1SDimitry Andric PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, 1159fe6060f1SDimitry Andric SDValue &Disp, SDValue &Base, 1160fe6060f1SDimitry Andric SelectionDAG &DAG, 1161fe6060f1SDimitry Andric MaybeAlign Align) const; 1162fe6060f1SDimitry Andric /// SelectForceXFormMode - Given the specified address, force it to be 1163fe6060f1SDimitry Andric /// represented as an indexed [r+r] operation (an XForm instruction). 1164fe6060f1SDimitry Andric PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, 1165fe6060f1SDimitry Andric SelectionDAG &DAG) const; 1166fe6060f1SDimitry Andric 1167bdd1243dSDimitry Andric bool splitValueIntoRegisterParts( 1168bdd1243dSDimitry Andric SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, 1169bdd1243dSDimitry Andric unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC) 1170bdd1243dSDimitry Andric const override; 11715ffd83dbSDimitry Andric /// Structure that collects some common arguments that get passed around 11725ffd83dbSDimitry Andric /// between the functions for call lowering. 11735ffd83dbSDimitry Andric struct CallFlags { 11745ffd83dbSDimitry Andric const CallingConv::ID CallConv; 11755ffd83dbSDimitry Andric const bool IsTailCall : 1; 11765ffd83dbSDimitry Andric const bool IsVarArg : 1; 11775ffd83dbSDimitry Andric const bool IsPatchPoint : 1; 11785ffd83dbSDimitry Andric const bool IsIndirect : 1; 11795ffd83dbSDimitry Andric const bool HasNest : 1; 11805ffd83dbSDimitry Andric const bool NoMerge : 1; 11815ffd83dbSDimitry Andric CallFlagsCallFlags11825ffd83dbSDimitry Andric CallFlags(CallingConv::ID CC, bool IsTailCall, bool IsVarArg, 11835ffd83dbSDimitry Andric bool IsPatchPoint, bool IsIndirect, bool HasNest, bool NoMerge) 11845ffd83dbSDimitry Andric : CallConv(CC), IsTailCall(IsTailCall), IsVarArg(IsVarArg), 11855ffd83dbSDimitry Andric IsPatchPoint(IsPatchPoint), IsIndirect(IsIndirect), 11865ffd83dbSDimitry Andric HasNest(HasNest), NoMerge(NoMerge) {} 11875ffd83dbSDimitry Andric }; 11885ffd83dbSDimitry Andric 1189fe6060f1SDimitry Andric CCAssignFn *ccAssignFnForCall(CallingConv::ID CC, bool Return, 1190fe6060f1SDimitry Andric bool IsVarArg) const; 119106c3fb27SDimitry Andric bool supportsTailCallFor(const CallBase *CB) const; 1192fe6060f1SDimitry Andric 11930b57cec5SDimitry Andric private: 11940b57cec5SDimitry Andric struct ReuseLoadInfo { 11950b57cec5SDimitry Andric SDValue Ptr; 11960b57cec5SDimitry Andric SDValue Chain; 11970b57cec5SDimitry Andric SDValue ResChain; 11980b57cec5SDimitry Andric MachinePointerInfo MPI; 11990b57cec5SDimitry Andric bool IsDereferenceable = false; 12000b57cec5SDimitry Andric bool IsInvariant = false; 12015ffd83dbSDimitry Andric Align Alignment; 12020b57cec5SDimitry Andric AAMDNodes AAInfo; 12030b57cec5SDimitry Andric const MDNode *Ranges = nullptr; 12040b57cec5SDimitry Andric 12050b57cec5SDimitry Andric ReuseLoadInfo() = default; 12060b57cec5SDimitry Andric MMOFlagsReuseLoadInfo12070b57cec5SDimitry Andric MachineMemOperand::Flags MMOFlags() const { 12080b57cec5SDimitry Andric MachineMemOperand::Flags F = MachineMemOperand::MONone; 12090b57cec5SDimitry Andric if (IsDereferenceable) 12100b57cec5SDimitry Andric F |= MachineMemOperand::MODereferenceable; 12110b57cec5SDimitry Andric if (IsInvariant) 12120b57cec5SDimitry Andric F |= MachineMemOperand::MOInvariant; 12130b57cec5SDimitry Andric return F; 12140b57cec5SDimitry Andric } 12150b57cec5SDimitry Andric }; 12160b57cec5SDimitry Andric 1217fe6060f1SDimitry Andric // Map that relates a set of common address flags to PPC addressing modes. 1218fe6060f1SDimitry Andric std::map<PPC::AddrMode, SmallVector<unsigned, 16>> AddrModesMap; 1219fe6060f1SDimitry Andric void initializeAddrModeMap(); 1220fe6060f1SDimitry Andric 12210b57cec5SDimitry Andric bool canReuseLoadAddress(SDValue Op, EVT MemVT, ReuseLoadInfo &RLI, 12220b57cec5SDimitry Andric SelectionDAG &DAG, 12230b57cec5SDimitry Andric ISD::LoadExtType ET = ISD::NON_EXTLOAD) const; 12240b57cec5SDimitry Andric void spliceIntoChain(SDValue ResChain, SDValue NewResChain, 12250b57cec5SDimitry Andric SelectionDAG &DAG) const; 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric void LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI, 12280b57cec5SDimitry Andric SelectionDAG &DAG, const SDLoc &dl) const; 12290b57cec5SDimitry Andric SDValue LowerFP_TO_INTDirectMove(SDValue Op, SelectionDAG &DAG, 12300b57cec5SDimitry Andric const SDLoc &dl) const; 12310b57cec5SDimitry Andric 12320b57cec5SDimitry Andric bool directMoveIsProfitable(const SDValue &Op) const; 12330b57cec5SDimitry Andric SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG &DAG, 12340b57cec5SDimitry Andric const SDLoc &dl) const; 12350b57cec5SDimitry Andric 12360b57cec5SDimitry Andric SDValue LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG, 12370b57cec5SDimitry Andric const SDLoc &dl) const; 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric SDValue LowerTRUNCATEVector(SDValue Op, SelectionDAG &DAG) const; 12400b57cec5SDimitry Andric 12410b57cec5SDimitry Andric SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const; 12420b57cec5SDimitry Andric SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const; 12430b57cec5SDimitry Andric 124406c3fb27SDimitry Andric bool IsEligibleForTailCallOptimization( 124506c3fb27SDimitry Andric const GlobalValue *CalleeGV, CallingConv::ID CalleeCC, 124606c3fb27SDimitry Andric CallingConv::ID CallerCC, bool isVarArg, 124706c3fb27SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins) const; 12480b57cec5SDimitry Andric 12495ffd83dbSDimitry Andric bool IsEligibleForTailCallOptimization_64SVR4( 125006c3fb27SDimitry Andric const GlobalValue *CalleeGV, CallingConv::ID CalleeCC, 125106c3fb27SDimitry Andric CallingConv::ID CallerCC, const CallBase *CB, bool isVarArg, 125206c3fb27SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 125306c3fb27SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, const Function *CallerFunc, 125406c3fb27SDimitry Andric bool isCalleeExternalSymbol) const; 125506c3fb27SDimitry Andric 125606c3fb27SDimitry Andric bool isEligibleForTCO(const GlobalValue *CalleeGV, CallingConv::ID CalleeCC, 125706c3fb27SDimitry Andric CallingConv::ID CallerCC, const CallBase *CB, 125806c3fb27SDimitry Andric bool isVarArg, 125906c3fb27SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 126006c3fb27SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 126106c3fb27SDimitry Andric const Function *CallerFunc, 126206c3fb27SDimitry Andric bool isCalleeExternalSymbol) const; 12630b57cec5SDimitry Andric 12640b57cec5SDimitry Andric SDValue EmitTailCallLoadFPAndRetAddr(SelectionDAG &DAG, int SPDiff, 12650b57cec5SDimitry Andric SDValue Chain, SDValue &LROpOut, 12660b57cec5SDimitry Andric SDValue &FPOpOut, 12670b57cec5SDimitry Andric const SDLoc &dl) const; 12680b57cec5SDimitry Andric 12698bcb0991SDimitry Andric SDValue getTOCEntry(SelectionDAG &DAG, const SDLoc &dl, SDValue GA) const; 12708bcb0991SDimitry Andric 12710b57cec5SDimitry Andric SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 12720b57cec5SDimitry Andric SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 12730b57cec5SDimitry Andric SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 12740b57cec5SDimitry Andric SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 12750b57cec5SDimitry Andric SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; 1276fe6060f1SDimitry Andric SDValue LowerGlobalTLSAddressAIX(SDValue Op, SelectionDAG &DAG) const; 1277fe6060f1SDimitry Andric SDValue LowerGlobalTLSAddressLinux(SDValue Op, SelectionDAG &DAG) const; 12780b57cec5SDimitry Andric SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 12790b57cec5SDimitry Andric SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 12800b57cec5SDimitry Andric SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; 12810b57cec5SDimitry Andric SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; 12820b57cec5SDimitry Andric SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; 128323408297SDimitry Andric SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; 12840b57cec5SDimitry Andric SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 12850b57cec5SDimitry Andric SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; 12860b57cec5SDimitry Andric SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const; 12870b57cec5SDimitry Andric SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; 12880b57cec5SDimitry Andric SDValue LowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const; 12890b57cec5SDimitry Andric SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 12900b57cec5SDimitry Andric SDValue LowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const; 12910b57cec5SDimitry Andric SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; 12920b57cec5SDimitry Andric SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; 12930b57cec5SDimitry Andric SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const; 12940b57cec5SDimitry Andric SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 12950b57cec5SDimitry Andric SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, 12960b57cec5SDimitry Andric const SDLoc &dl) const; 12970b57cec5SDimitry Andric SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const; 1298bdd1243dSDimitry Andric SDValue LowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const; 12990b57cec5SDimitry Andric SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const; 13000b57cec5SDimitry Andric SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const; 13010b57cec5SDimitry Andric SDValue LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const; 1302e8d8bef9SDimitry Andric SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) const; 13030b57cec5SDimitry Andric SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; 13040b57cec5SDimitry Andric SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; 1305bdd1243dSDimitry Andric SDValue LowerVPERM(SDValue Op, SelectionDAG &DAG, ArrayRef<int> PermMask, 1306bdd1243dSDimitry Andric EVT VT, SDValue V1, SDValue V2) const; 13070b57cec5SDimitry Andric SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; 13080b57cec5SDimitry Andric SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; 13090b57cec5SDimitry Andric SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; 13100b57cec5SDimitry Andric SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const; 13110b57cec5SDimitry Andric SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const; 131206c3fb27SDimitry Andric SDValue LowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const; 131381ad6265SDimitry Andric SDValue lowerToLibCall(const char *LibCallName, SDValue Op, 131481ad6265SDimitry Andric SelectionDAG &DAG) const; 131581ad6265SDimitry Andric SDValue lowerLibCallBasedOnType(const char *LibCallFloatName, 131681ad6265SDimitry Andric const char *LibCallDoubleName, SDValue Op, 131781ad6265SDimitry Andric SelectionDAG &DAG) const; 131881ad6265SDimitry Andric bool isLowringToMASSFiniteSafe(SDValue Op) const; 131981ad6265SDimitry Andric bool isLowringToMASSSafe(SDValue Op) const; 1320753f127fSDimitry Andric bool isScalarMASSConversionEnabled() const; 132181ad6265SDimitry Andric SDValue lowerLibCallBase(const char *LibCallDoubleName, 132281ad6265SDimitry Andric const char *LibCallFloatName, 132381ad6265SDimitry Andric const char *LibCallDoubleNameFinite, 132481ad6265SDimitry Andric const char *LibCallFloatNameFinite, SDValue Op, 132581ad6265SDimitry Andric SelectionDAG &DAG) const; 132681ad6265SDimitry Andric SDValue lowerPow(SDValue Op, SelectionDAG &DAG) const; 132781ad6265SDimitry Andric SDValue lowerSin(SDValue Op, SelectionDAG &DAG) const; 132881ad6265SDimitry Andric SDValue lowerCos(SDValue Op, SelectionDAG &DAG) const; 132981ad6265SDimitry Andric SDValue lowerLog(SDValue Op, SelectionDAG &DAG) const; 133081ad6265SDimitry Andric SDValue lowerLog10(SDValue Op, SelectionDAG &DAG) const; 133181ad6265SDimitry Andric SDValue lowerExp(SDValue Op, SelectionDAG &DAG) const; 1332349cc55cSDimitry Andric SDValue LowerATOMIC_LOAD_STORE(SDValue Op, SelectionDAG &DAG) const; 13330b57cec5SDimitry Andric SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const; 13340b57cec5SDimitry Andric SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const; 13350b57cec5SDimitry Andric SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const; 1336e8d8bef9SDimitry Andric SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const; 13375ffd83dbSDimitry Andric SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const; 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric SDValue LowerVectorLoad(SDValue Op, SelectionDAG &DAG) const; 13400b57cec5SDimitry Andric SDValue LowerVectorStore(SDValue Op, SelectionDAG &DAG) const; 13410b57cec5SDimitry Andric 134206c3fb27SDimitry Andric SDValue LowerCallResult(SDValue Chain, SDValue InGlue, 13430b57cec5SDimitry Andric CallingConv::ID CallConv, bool isVarArg, 13440b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 13450b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 13460b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const; 13475ffd83dbSDimitry Andric 13485ffd83dbSDimitry Andric SDValue FinishCall(CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, 13490b57cec5SDimitry Andric SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, 135006c3fb27SDimitry Andric SDValue InGlue, SDValue Chain, SDValue CallSeqStart, 13510b57cec5SDimitry Andric SDValue &Callee, int SPDiff, unsigned NumBytes, 13520b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 13530b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals, 13545ffd83dbSDimitry Andric const CallBase *CB) const; 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric SDValue 13570b57cec5SDimitry Andric LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 13580b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 13590b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 13600b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 13610b57cec5SDimitry Andric 13620b57cec5SDimitry Andric SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, 13630b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals) const override; 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 13660b57cec5SDimitry Andric bool isVarArg, 13670b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 13680b57cec5SDimitry Andric LLVMContext &Context) const override; 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 13710b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 13720b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 13730b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG) const override; 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric SDValue extendArgForPPC64(ISD::ArgFlagsTy Flags, EVT ObjectVT, 13760b57cec5SDimitry Andric SelectionDAG &DAG, SDValue ArgVal, 13770b57cec5SDimitry Andric const SDLoc &dl) const; 13780b57cec5SDimitry Andric 1379480093f4SDimitry Andric SDValue LowerFormalArguments_AIX( 1380480093f4SDimitry Andric SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1381480093f4SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 1382480093f4SDimitry Andric SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; 13830b57cec5SDimitry Andric SDValue LowerFormalArguments_64SVR4( 13840b57cec5SDimitry Andric SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 13850b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 13860b57cec5SDimitry Andric SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; 13870b57cec5SDimitry Andric SDValue LowerFormalArguments_32SVR4( 13880b57cec5SDimitry Andric SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 13890b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, 13900b57cec5SDimitry Andric SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const; 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andric SDValue createMemcpyOutsideCallSeq(SDValue Arg, SDValue PtrOff, 13930b57cec5SDimitry Andric SDValue CallSeqStart, 13940b57cec5SDimitry Andric ISD::ArgFlagsTy Flags, SelectionDAG &DAG, 13950b57cec5SDimitry Andric const SDLoc &dl) const; 13960b57cec5SDimitry Andric 13975ffd83dbSDimitry Andric SDValue LowerCall_64SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags, 13980b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 13990b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 14000b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 14010b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 14020b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals, 14035ffd83dbSDimitry Andric const CallBase *CB) const; 14045ffd83dbSDimitry Andric SDValue LowerCall_32SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags, 14050b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 14060b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 14070b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 14080b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 14090b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals, 14105ffd83dbSDimitry Andric const CallBase *CB) const; 14115ffd83dbSDimitry Andric SDValue LowerCall_AIX(SDValue Chain, SDValue Callee, CallFlags CFlags, 14120b57cec5SDimitry Andric const SmallVectorImpl<ISD::OutputArg> &Outs, 14130b57cec5SDimitry Andric const SmallVectorImpl<SDValue> &OutVals, 14140b57cec5SDimitry Andric const SmallVectorImpl<ISD::InputArg> &Ins, 14150b57cec5SDimitry Andric const SDLoc &dl, SelectionDAG &DAG, 14160b57cec5SDimitry Andric SmallVectorImpl<SDValue> &InVals, 14175ffd83dbSDimitry Andric const CallBase *CB) const; 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const; 14200b57cec5SDimitry Andric SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const; 14210b57cec5SDimitry Andric SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const; 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric SDValue DAGCombineExtBoolTrunc(SDNode *N, DAGCombinerInfo &DCI) const; 14240b57cec5SDimitry Andric SDValue DAGCombineBuildVector(SDNode *N, DAGCombinerInfo &DCI) const; 14250b57cec5SDimitry Andric SDValue DAGCombineTruncBoolExt(SDNode *N, DAGCombinerInfo &DCI) const; 14260b57cec5SDimitry Andric SDValue combineStoreFPToInt(SDNode *N, DAGCombinerInfo &DCI) const; 14270b57cec5SDimitry Andric SDValue combineFPToIntToFP(SDNode *N, DAGCombinerInfo &DCI) const; 14280b57cec5SDimitry Andric SDValue combineSHL(SDNode *N, DAGCombinerInfo &DCI) const; 14290b57cec5SDimitry Andric SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const; 14300b57cec5SDimitry Andric SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const; 14310b57cec5SDimitry Andric SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const; 14320b57cec5SDimitry Andric SDValue combineADD(SDNode *N, DAGCombinerInfo &DCI) const; 14335ffd83dbSDimitry Andric SDValue combineFMALike(SDNode *N, DAGCombinerInfo &DCI) const; 14340b57cec5SDimitry Andric SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const; 14350b57cec5SDimitry Andric SDValue combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const; 14365ffd83dbSDimitry Andric SDValue combineVectorShuffle(ShuffleVectorSDNode *SVN, 14375ffd83dbSDimitry Andric SelectionDAG &DAG) const; 14388bcb0991SDimitry Andric SDValue combineVReverseMemOP(ShuffleVectorSDNode *SVN, LSBaseSDNode *LSBase, 14398bcb0991SDimitry Andric DAGCombinerInfo &DCI) const; 14400b57cec5SDimitry Andric 14410b57cec5SDimitry Andric /// ConvertSETCCToSubtract - looks at SETCC that compares ints. It replaces 14420b57cec5SDimitry Andric /// SETCC with integer subtraction when (1) there is a legal way of doing it 14430b57cec5SDimitry Andric /// (2) keeping the result of comparison in GPR has performance benefit. 14440b57cec5SDimitry Andric SDValue ConvertSETCCToSubtract(SDNode *N, DAGCombinerInfo &DCI) const; 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, 14470b57cec5SDimitry Andric int &RefinementSteps, bool &UseOneConstNR, 14480b57cec5SDimitry Andric bool Reciprocal) const override; 14490b57cec5SDimitry Andric SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled, 14500b57cec5SDimitry Andric int &RefinementSteps) const override; 1451e8d8bef9SDimitry Andric SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, 1452e8d8bef9SDimitry Andric const DenormalMode &Mode) const override; 1453e8d8bef9SDimitry Andric SDValue getSqrtResultForDenormInput(SDValue Operand, 1454e8d8bef9SDimitry Andric SelectionDAG &DAG) const override; 14550b57cec5SDimitry Andric unsigned combineRepeatedFPDivisors() const override; 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric SDValue 14580b57cec5SDimitry Andric combineElementTruncationToVectorTruncation(SDNode *N, 14590b57cec5SDimitry Andric DAGCombinerInfo &DCI) const; 14600b57cec5SDimitry Andric 14610b57cec5SDimitry Andric /// lowerToVINSERTH - Return the SDValue if this VECTOR_SHUFFLE can be 14620b57cec5SDimitry Andric /// handled by the VINSERTH instruction introduced in ISA 3.0. This is 14630b57cec5SDimitry Andric /// essentially any shuffle of v8i16 vectors that just inserts one element 14640b57cec5SDimitry Andric /// from one vector into the other. 14650b57cec5SDimitry Andric SDValue lowerToVINSERTH(ShuffleVectorSDNode *N, SelectionDAG &DAG) const; 14660b57cec5SDimitry Andric 14670b57cec5SDimitry Andric /// lowerToVINSERTB - Return the SDValue if this VECTOR_SHUFFLE can be 14680b57cec5SDimitry Andric /// handled by the VINSERTB instruction introduced in ISA 3.0. This is 14690b57cec5SDimitry Andric /// essentially v16i8 vector version of VINSERTH. 14700b57cec5SDimitry Andric SDValue lowerToVINSERTB(ShuffleVectorSDNode *N, SelectionDAG &DAG) const; 14710b57cec5SDimitry Andric 14725ffd83dbSDimitry Andric /// lowerToXXSPLTI32DX - Return the SDValue if this VECTOR_SHUFFLE can be 14735ffd83dbSDimitry Andric /// handled by the XXSPLTI32DX instruction introduced in ISA 3.1. 14745ffd83dbSDimitry Andric SDValue lowerToXXSPLTI32DX(ShuffleVectorSDNode *N, SelectionDAG &DAG) const; 14755ffd83dbSDimitry Andric 14760b57cec5SDimitry Andric // Return whether the call instruction can potentially be optimized to a 14770b57cec5SDimitry Andric // tail call. This will cause the optimizers to attempt to move, or 14780b57cec5SDimitry Andric // duplicate return instructions to help enable tail call optimizations. 14790b57cec5SDimitry Andric bool mayBeEmittedAsTailCall(const CallInst *CI) const override; 14800b57cec5SDimitry Andric bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override; 1481fe6060f1SDimitry Andric 1482fe6060f1SDimitry Andric /// getAddrModeForFlags - Based on the set of address flags, select the most 1483fe6060f1SDimitry Andric /// optimal instruction format to match by. 1484fe6060f1SDimitry Andric PPC::AddrMode getAddrModeForFlags(unsigned Flags) const; 1485fe6060f1SDimitry Andric 1486fe6060f1SDimitry Andric /// computeMOFlags - Given a node N and it's Parent (a MemSDNode), compute 1487fe6060f1SDimitry Andric /// the address flags of the load/store instruction that is to be matched. 1488fe6060f1SDimitry Andric /// The address flags are stored in a map, which is then searched 1489fe6060f1SDimitry Andric /// through to determine the optimal load/store instruction format. 1490fe6060f1SDimitry Andric unsigned computeMOFlags(const SDNode *Parent, SDValue N, 1491fe6060f1SDimitry Andric SelectionDAG &DAG) const; 14920b57cec5SDimitry Andric }; // end class PPCTargetLowering 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric namespace PPC { 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric FastISel *createFastISel(FunctionLoweringInfo &FuncInfo, 14970b57cec5SDimitry Andric const TargetLibraryInfo *LibInfo); 14980b57cec5SDimitry Andric 14990b57cec5SDimitry Andric } // end namespace PPC 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric bool isIntS16Immediate(SDNode *N, int16_t &Imm); 15020b57cec5SDimitry Andric bool isIntS16Immediate(SDValue Op, int16_t &Imm); 1503e8d8bef9SDimitry Andric bool isIntS34Immediate(SDNode *N, int64_t &Imm); 1504e8d8bef9SDimitry Andric bool isIntS34Immediate(SDValue Op, int64_t &Imm); 15050b57cec5SDimitry Andric 15065ffd83dbSDimitry Andric bool convertToNonDenormSingle(APInt &ArgAPInt); 15075ffd83dbSDimitry Andric bool convertToNonDenormSingle(APFloat &ArgAPFloat); 1508fe6060f1SDimitry Andric bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat); 15095ffd83dbSDimitry Andric 15100b57cec5SDimitry Andric } // end namespace llvm 15110b57cec5SDimitry Andric 151204eeddc0SDimitry Andric #endif // LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H 1513