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