xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCISelLowering.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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