106f32e7eSjoerg //===-- PPCISelLowering.h - PPC32 DAG Lowering Interface --------*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file defines the interfaces that PPC uses to lower LLVM code into a
1006f32e7eSjoerg // selection DAG.
1106f32e7eSjoerg //
1206f32e7eSjoerg //===----------------------------------------------------------------------===//
1306f32e7eSjoerg 
1406f32e7eSjoerg #ifndef LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H
1506f32e7eSjoerg #define LLVM_LIB_TARGET_POWERPC_PPCISELLOWERING_H
1606f32e7eSjoerg 
1706f32e7eSjoerg #include "PPCInstrInfo.h"
1806f32e7eSjoerg #include "llvm/CodeGen/CallingConvLower.h"
1906f32e7eSjoerg #include "llvm/CodeGen/MachineFunction.h"
2006f32e7eSjoerg #include "llvm/CodeGen/MachineMemOperand.h"
2106f32e7eSjoerg #include "llvm/CodeGen/SelectionDAG.h"
2206f32e7eSjoerg #include "llvm/CodeGen/SelectionDAGNodes.h"
2306f32e7eSjoerg #include "llvm/CodeGen/TargetLowering.h"
2406f32e7eSjoerg #include "llvm/CodeGen/ValueTypes.h"
2506f32e7eSjoerg #include "llvm/IR/Attributes.h"
2606f32e7eSjoerg #include "llvm/IR/CallingConv.h"
2706f32e7eSjoerg #include "llvm/IR/Function.h"
2806f32e7eSjoerg #include "llvm/IR/InlineAsm.h"
2906f32e7eSjoerg #include "llvm/IR/Metadata.h"
3006f32e7eSjoerg #include "llvm/IR/Type.h"
3106f32e7eSjoerg #include "llvm/Support/MachineValueType.h"
3206f32e7eSjoerg #include <utility>
3306f32e7eSjoerg 
3406f32e7eSjoerg namespace llvm {
3506f32e7eSjoerg 
3606f32e7eSjoerg   namespace PPCISD {
3706f32e7eSjoerg 
3806f32e7eSjoerg     // When adding a NEW PPCISD node please add it to the correct position in
3906f32e7eSjoerg     // the enum. The order of elements in this enum matters!
4006f32e7eSjoerg     // Values that are added after this entry:
4106f32e7eSjoerg     //     STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE
4206f32e7eSjoerg     // are considered memory opcodes and are treated differently than entries
4306f32e7eSjoerg     // that come before it. For example, ADD or MUL should be placed before
4406f32e7eSjoerg     // the ISD::FIRST_TARGET_MEMORY_OPCODE while a LOAD or STORE should come
4506f32e7eSjoerg     // after it.
4606f32e7eSjoerg   enum NodeType : unsigned {
4706f32e7eSjoerg     // Start the numbering where the builtin ops and target ops leave off.
4806f32e7eSjoerg     FIRST_NUMBER = ISD::BUILTIN_OP_END,
4906f32e7eSjoerg 
5006f32e7eSjoerg     /// FSEL - Traditional three-operand fsel node.
5106f32e7eSjoerg     ///
5206f32e7eSjoerg     FSEL,
5306f32e7eSjoerg 
54*da58b97aSjoerg     /// XSMAXCDP, XSMINCDP - C-type min/max instructions.
55*da58b97aSjoerg     XSMAXCDP,
56*da58b97aSjoerg     XSMINCDP,
57*da58b97aSjoerg 
5806f32e7eSjoerg     /// FCFID - The FCFID instruction, taking an f64 operand and producing
5906f32e7eSjoerg     /// and f64 value containing the FP representation of the integer that
6006f32e7eSjoerg     /// was temporarily in the f64 operand.
6106f32e7eSjoerg     FCFID,
6206f32e7eSjoerg 
6306f32e7eSjoerg     /// Newer FCFID[US] integer-to-floating-point conversion instructions for
6406f32e7eSjoerg     /// unsigned integers and single-precision outputs.
65*da58b97aSjoerg     FCFIDU,
66*da58b97aSjoerg     FCFIDS,
67*da58b97aSjoerg     FCFIDUS,
6806f32e7eSjoerg 
6906f32e7eSjoerg     /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64
7006f32e7eSjoerg     /// operand, producing an f64 value containing the integer representation
7106f32e7eSjoerg     /// of that FP value.
72*da58b97aSjoerg     FCTIDZ,
73*da58b97aSjoerg     FCTIWZ,
7406f32e7eSjoerg 
7506f32e7eSjoerg     /// Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for
7606f32e7eSjoerg     /// unsigned integers with round toward zero.
77*da58b97aSjoerg     FCTIDUZ,
78*da58b97aSjoerg     FCTIWUZ,
7906f32e7eSjoerg 
8006f32e7eSjoerg     /// Floating-point-to-interger conversion instructions
81*da58b97aSjoerg     FP_TO_UINT_IN_VSR,
82*da58b97aSjoerg     FP_TO_SINT_IN_VSR,
8306f32e7eSjoerg 
8406f32e7eSjoerg     /// VEXTS, ByteWidth - takes an input in VSFRC and produces an output in
8506f32e7eSjoerg     /// VSFRC that is sign-extended from ByteWidth to a 64-byte integer.
8606f32e7eSjoerg     VEXTS,
8706f32e7eSjoerg 
8806f32e7eSjoerg     /// Reciprocal estimate instructions (unary FP ops).
89*da58b97aSjoerg     FRE,
90*da58b97aSjoerg     FRSQRTE,
9106f32e7eSjoerg 
92*da58b97aSjoerg     /// Test instruction for software square root.
93*da58b97aSjoerg     FTSQRT,
94*da58b97aSjoerg 
95*da58b97aSjoerg     /// Square root instruction.
96*da58b97aSjoerg     FSQRT,
9706f32e7eSjoerg 
9806f32e7eSjoerg     /// VPERM - The PPC VPERM Instruction.
9906f32e7eSjoerg     ///
10006f32e7eSjoerg     VPERM,
10106f32e7eSjoerg 
10206f32e7eSjoerg     /// XXSPLT - The PPC VSX splat instructions
10306f32e7eSjoerg     ///
10406f32e7eSjoerg     XXSPLT,
10506f32e7eSjoerg 
106*da58b97aSjoerg     /// XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for
107*da58b97aSjoerg     /// converting immediate single precision numbers to double precision
108*da58b97aSjoerg     /// vector or scalar.
109*da58b97aSjoerg     XXSPLTI_SP_TO_DP,
110*da58b97aSjoerg 
111*da58b97aSjoerg     /// XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
112*da58b97aSjoerg     ///
113*da58b97aSjoerg     XXSPLTI32DX,
114*da58b97aSjoerg 
11506f32e7eSjoerg     /// VECINSERT - The PPC vector insert instruction
11606f32e7eSjoerg     ///
11706f32e7eSjoerg     VECINSERT,
11806f32e7eSjoerg 
11906f32e7eSjoerg     /// VECSHL - The PPC vector shift left instruction
12006f32e7eSjoerg     ///
12106f32e7eSjoerg     VECSHL,
12206f32e7eSjoerg 
12306f32e7eSjoerg     /// XXPERMDI - The PPC XXPERMDI instruction
12406f32e7eSjoerg     ///
12506f32e7eSjoerg     XXPERMDI,
12606f32e7eSjoerg 
12706f32e7eSjoerg     /// The CMPB instruction (takes two operands of i32 or i64).
12806f32e7eSjoerg     CMPB,
12906f32e7eSjoerg 
13006f32e7eSjoerg     /// Hi/Lo - These represent the high and low 16-bit parts of a global
13106f32e7eSjoerg     /// address respectively.  These nodes have two operands, the first of
13206f32e7eSjoerg     /// which must be a TargetGlobalAddress, and the second of which must be a
13306f32e7eSjoerg     /// Constant.  Selected naively, these turn into 'lis G+C' and 'li G+C',
13406f32e7eSjoerg     /// though these are usually folded into other nodes.
135*da58b97aSjoerg     Hi,
136*da58b97aSjoerg     Lo,
13706f32e7eSjoerg 
13806f32e7eSjoerg     /// The following two target-specific nodes are used for calls through
13906f32e7eSjoerg     /// function pointers in the 64-bit SVR4 ABI.
14006f32e7eSjoerg 
14106f32e7eSjoerg     /// OPRC, CHAIN = DYNALLOC(CHAIN, NEGSIZE, FRAME_INDEX)
14206f32e7eSjoerg     /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to
14306f32e7eSjoerg     /// compute an allocation on the stack.
14406f32e7eSjoerg     DYNALLOC,
14506f32e7eSjoerg 
14606f32e7eSjoerg     /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to
14706f32e7eSjoerg     /// compute an offset from native SP to the address  of the most recent
14806f32e7eSjoerg     /// dynamic alloca.
14906f32e7eSjoerg     DYNAREAOFFSET,
15006f32e7eSjoerg 
151*da58b97aSjoerg     /// To avoid stack clash, allocation is performed by block and each block is
152*da58b97aSjoerg     /// probed.
153*da58b97aSjoerg     PROBED_ALLOCA,
154*da58b97aSjoerg 
155*da58b97aSjoerg     /// The result of the mflr at function entry, used for PIC code.
15606f32e7eSjoerg     GlobalBaseReg,
15706f32e7eSjoerg 
15806f32e7eSjoerg     /// These nodes represent PPC shifts.
15906f32e7eSjoerg     ///
16006f32e7eSjoerg     /// For scalar types, only the last `n + 1` bits of the shift amounts
16106f32e7eSjoerg     /// are used, where n is log2(sizeof(element) * 8). See sld/slw, etc.
16206f32e7eSjoerg     /// for exact behaviors.
16306f32e7eSjoerg     ///
16406f32e7eSjoerg     /// For vector types, only the last n bits are used. See vsld.
165*da58b97aSjoerg     SRL,
166*da58b97aSjoerg     SRA,
167*da58b97aSjoerg     SHL,
168*da58b97aSjoerg 
169*da58b97aSjoerg     /// FNMSUB - Negated multiply-subtract instruction.
170*da58b97aSjoerg     FNMSUB,
17106f32e7eSjoerg 
17206f32e7eSjoerg     /// EXTSWSLI = The PPC extswsli instruction, which does an extend-sign
17306f32e7eSjoerg     /// word and shift left immediate.
17406f32e7eSjoerg     EXTSWSLI,
17506f32e7eSjoerg 
17606f32e7eSjoerg     /// The combination of sra[wd]i and addze used to implemented signed
17706f32e7eSjoerg     /// integer division by a power of 2. The first operand is the dividend,
17806f32e7eSjoerg     /// and the second is the constant shift amount (representing the
17906f32e7eSjoerg     /// divisor).
18006f32e7eSjoerg     SRA_ADDZE,
18106f32e7eSjoerg 
18206f32e7eSjoerg     /// CALL - A direct function call.
18306f32e7eSjoerg     /// CALL_NOP is a call with the special NOP which follows 64-bit
184*da58b97aSjoerg     /// CALL_NOTOC the caller does not use the TOC.
18506f32e7eSjoerg     /// SVR4 calls and 32-bit/64-bit AIX calls.
186*da58b97aSjoerg     CALL,
187*da58b97aSjoerg     CALL_NOP,
188*da58b97aSjoerg     CALL_NOTOC,
18906f32e7eSjoerg 
19006f32e7eSjoerg     /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a
19106f32e7eSjoerg     /// MTCTR instruction.
19206f32e7eSjoerg     MTCTR,
19306f32e7eSjoerg 
19406f32e7eSjoerg     /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a
19506f32e7eSjoerg     /// BCTRL instruction.
19606f32e7eSjoerg     BCTRL,
19706f32e7eSjoerg 
19806f32e7eSjoerg     /// CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl
199*da58b97aSjoerg     /// instruction and the TOC reload required on 64-bit ELF, 32-bit AIX
200*da58b97aSjoerg     /// and 64-bit AIX.
20106f32e7eSjoerg     BCTRL_LOAD_TOC,
20206f32e7eSjoerg 
20306f32e7eSjoerg     /// Return with a flag operand, matched by 'blr'
20406f32e7eSjoerg     RET_FLAG,
20506f32e7eSjoerg 
20606f32e7eSjoerg     /// R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
20706f32e7eSjoerg     /// This copies the bits corresponding to the specified CRREG into the
20806f32e7eSjoerg     /// resultant GPR.  Bits corresponding to other CR regs are undefined.
20906f32e7eSjoerg     MFOCRF,
21006f32e7eSjoerg 
21106f32e7eSjoerg     /// Direct move from a VSX register to a GPR
21206f32e7eSjoerg     MFVSR,
21306f32e7eSjoerg 
21406f32e7eSjoerg     /// Direct move from a GPR to a VSX register (algebraic)
21506f32e7eSjoerg     MTVSRA,
21606f32e7eSjoerg 
21706f32e7eSjoerg     /// Direct move from a GPR to a VSX register (zero)
21806f32e7eSjoerg     MTVSRZ,
21906f32e7eSjoerg 
22006f32e7eSjoerg     /// Direct move of 2 consecutive GPR to a VSX register.
22106f32e7eSjoerg     BUILD_FP128,
22206f32e7eSjoerg 
22306f32e7eSjoerg     /// BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and
22406f32e7eSjoerg     /// EXTRACT_ELEMENT but take f64 arguments instead of i64, as i64 is
22506f32e7eSjoerg     /// unsupported for this target.
22606f32e7eSjoerg     /// Merge 2 GPRs to a single SPE register.
22706f32e7eSjoerg     BUILD_SPE64,
22806f32e7eSjoerg 
22906f32e7eSjoerg     /// Extract SPE register component, second argument is high or low.
23006f32e7eSjoerg     EXTRACT_SPE,
23106f32e7eSjoerg 
23206f32e7eSjoerg     /// Extract a subvector from signed integer vector and convert to FP.
23306f32e7eSjoerg     /// It is primarily used to convert a (widened) illegal integer vector
23406f32e7eSjoerg     /// type to a legal floating point vector type.
23506f32e7eSjoerg     /// For example v2i32 -> widened to v4i32 -> v2f64
23606f32e7eSjoerg     SINT_VEC_TO_FP,
23706f32e7eSjoerg 
23806f32e7eSjoerg     /// Extract a subvector from unsigned integer vector and convert to FP.
23906f32e7eSjoerg     /// As with SINT_VEC_TO_FP, used for converting illegal types.
24006f32e7eSjoerg     UINT_VEC_TO_FP,
24106f32e7eSjoerg 
242*da58b97aSjoerg     /// PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to
243*da58b97aSjoerg     /// place the value into the least significant element of the most
244*da58b97aSjoerg     /// significant doubleword in the vector. This is not element zero for
245*da58b97aSjoerg     /// anything smaller than a doubleword on either endianness. This node has
246*da58b97aSjoerg     /// the same semantics as SCALAR_TO_VECTOR except that the value remains in
247*da58b97aSjoerg     /// the aforementioned location in the vector register.
248*da58b97aSjoerg     SCALAR_TO_VECTOR_PERMUTED,
249*da58b97aSjoerg 
25006f32e7eSjoerg     // FIXME: Remove these once the ANDI glue bug is fixed:
251*da58b97aSjoerg     /// i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the
25206f32e7eSjoerg     /// eq or gt bit of CR0 after executing andi. x, 1. This is used to
25306f32e7eSjoerg     /// implement truncation of i32 or i64 to i1.
254*da58b97aSjoerg     ANDI_rec_1_EQ_BIT,
255*da58b97aSjoerg     ANDI_rec_1_GT_BIT,
25606f32e7eSjoerg 
25706f32e7eSjoerg     // READ_TIME_BASE - A read of the 64-bit time-base register on a 32-bit
25806f32e7eSjoerg     // target (returns (Lo, Hi)). It takes a chain operand.
25906f32e7eSjoerg     READ_TIME_BASE,
26006f32e7eSjoerg 
26106f32e7eSjoerg     // EH_SJLJ_SETJMP - SjLj exception handling setjmp.
26206f32e7eSjoerg     EH_SJLJ_SETJMP,
26306f32e7eSjoerg 
26406f32e7eSjoerg     // EH_SJLJ_LONGJMP - SjLj exception handling longjmp.
26506f32e7eSjoerg     EH_SJLJ_LONGJMP,
26606f32e7eSjoerg 
26706f32e7eSjoerg     /// RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP*
26806f32e7eSjoerg     /// instructions.  For lack of better number, we use the opcode number
26906f32e7eSjoerg     /// encoding for the OPC field to identify the compare.  For example, 838
27006f32e7eSjoerg     /// is VCMPGTSH.
27106f32e7eSjoerg     VCMP,
27206f32e7eSjoerg 
273*da58b97aSjoerg     /// RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the
274*da58b97aSjoerg     /// altivec VCMP*_rec instructions.  For lack of better number, we use the
27506f32e7eSjoerg     /// opcode number encoding for the OPC field to identify the compare.  For
27606f32e7eSjoerg     /// example, 838 is VCMPGTSH.
277*da58b97aSjoerg     VCMP_rec,
27806f32e7eSjoerg 
27906f32e7eSjoerg     /// CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This
28006f32e7eSjoerg     /// corresponds to the COND_BRANCH pseudo instruction.  CRRC is the
28106f32e7eSjoerg     /// condition register to branch on, OPC is the branch opcode to use (e.g.
28206f32e7eSjoerg     /// PPC::BLE), DESTBB is the destination block to branch to, and INFLAG is
28306f32e7eSjoerg     /// an optional input flag argument.
28406f32e7eSjoerg     COND_BRANCH,
28506f32e7eSjoerg 
28606f32e7eSjoerg     /// CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based
28706f32e7eSjoerg     /// loops.
288*da58b97aSjoerg     BDNZ,
289*da58b97aSjoerg     BDZ,
29006f32e7eSjoerg 
29106f32e7eSjoerg     /// F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding
29206f32e7eSjoerg     /// towards zero.  Used only as part of the long double-to-int
29306f32e7eSjoerg     /// conversion sequence.
29406f32e7eSjoerg     FADDRTZ,
29506f32e7eSjoerg 
29606f32e7eSjoerg     /// F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
29706f32e7eSjoerg     MFFS,
29806f32e7eSjoerg 
29906f32e7eSjoerg     /// TC_RETURN - A tail call return.
30006f32e7eSjoerg     ///   operand #0 chain
30106f32e7eSjoerg     ///   operand #1 callee (register or absolute)
30206f32e7eSjoerg     ///   operand #2 stack adjustment
30306f32e7eSjoerg     ///   operand #3 optional in flag
30406f32e7eSjoerg     TC_RETURN,
30506f32e7eSjoerg 
30606f32e7eSjoerg     /// ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
30706f32e7eSjoerg     CR6SET,
30806f32e7eSjoerg     CR6UNSET,
30906f32e7eSjoerg 
31006f32e7eSjoerg     /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by initial-exec TLS
31106f32e7eSjoerg     /// for non-position independent code on PPC32.
31206f32e7eSjoerg     PPC32_GOT,
31306f32e7eSjoerg 
31406f32e7eSjoerg     /// GPRC = address of _GLOBAL_OFFSET_TABLE_. Used by general dynamic and
31506f32e7eSjoerg     /// local dynamic TLS and position indendepent code on PPC32.
31606f32e7eSjoerg     PPC32_PICGOT,
31706f32e7eSjoerg 
31806f32e7eSjoerg     /// G8RC = ADDIS_GOT_TPREL_HA %x2, Symbol - Used by the initial-exec
31906f32e7eSjoerg     /// TLS model, produces an ADDIS8 instruction that adds the GOT
32006f32e7eSjoerg     /// base to sym\@got\@tprel\@ha.
32106f32e7eSjoerg     ADDIS_GOT_TPREL_HA,
32206f32e7eSjoerg 
32306f32e7eSjoerg     /// G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec
32406f32e7eSjoerg     /// TLS model, produces a LD instruction with base register G8RReg
32506f32e7eSjoerg     /// and offset sym\@got\@tprel\@l.  This completes the addition that
32606f32e7eSjoerg     /// finds the offset of "sym" relative to the thread pointer.
32706f32e7eSjoerg     LD_GOT_TPREL_L,
32806f32e7eSjoerg 
32906f32e7eSjoerg     /// G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS
33006f32e7eSjoerg     /// model, produces an ADD instruction that adds the contents of
33106f32e7eSjoerg     /// G8RReg to the thread pointer.  Symbol contains a relocation
33206f32e7eSjoerg     /// sym\@tls which is to be replaced by the thread pointer and
33306f32e7eSjoerg     /// identifies to the linker that the instruction is part of a
33406f32e7eSjoerg     /// TLS sequence.
33506f32e7eSjoerg     ADD_TLS,
33606f32e7eSjoerg 
33706f32e7eSjoerg     /// G8RC = ADDIS_TLSGD_HA %x2, Symbol - For the general-dynamic TLS
33806f32e7eSjoerg     /// model, produces an ADDIS8 instruction that adds the GOT base
33906f32e7eSjoerg     /// register to sym\@got\@tlsgd\@ha.
34006f32e7eSjoerg     ADDIS_TLSGD_HA,
34106f32e7eSjoerg 
34206f32e7eSjoerg     /// %x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS
34306f32e7eSjoerg     /// model, produces an ADDI8 instruction that adds G8RReg to
34406f32e7eSjoerg     /// sym\@got\@tlsgd\@l and stores the result in X3.  Hidden by
34506f32e7eSjoerg     /// ADDIS_TLSGD_L_ADDR until after register assignment.
34606f32e7eSjoerg     ADDI_TLSGD_L,
34706f32e7eSjoerg 
34806f32e7eSjoerg     /// %x3 = GET_TLS_ADDR %x3, Symbol - For the general-dynamic TLS
34906f32e7eSjoerg     /// model, produces a call to __tls_get_addr(sym\@tlsgd).  Hidden by
35006f32e7eSjoerg     /// ADDIS_TLSGD_L_ADDR until after register assignment.
35106f32e7eSjoerg     GET_TLS_ADDR,
35206f32e7eSjoerg 
35306f32e7eSjoerg     /// G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that
35406f32e7eSjoerg     /// combines ADDI_TLSGD_L and GET_TLS_ADDR until expansion following
35506f32e7eSjoerg     /// register assignment.
35606f32e7eSjoerg     ADDI_TLSGD_L_ADDR,
35706f32e7eSjoerg 
358*da58b97aSjoerg     /// GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY
359*da58b97aSjoerg     /// G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY
360*da58b97aSjoerg     /// Op that combines two register copies of TOC entries
361*da58b97aSjoerg     /// (region handle into R3 and variable offset into R4) followed by a
362*da58b97aSjoerg     /// GET_TLS_ADDR node which will be expanded to a call to __get_tls_addr.
363*da58b97aSjoerg     /// This node is used in 64-bit mode as well (in which case the result is
364*da58b97aSjoerg     /// G8RC and inputs are X3/X4).
365*da58b97aSjoerg     TLSGD_AIX,
366*da58b97aSjoerg 
36706f32e7eSjoerg     /// G8RC = ADDIS_TLSLD_HA %x2, Symbol - For the local-dynamic TLS
36806f32e7eSjoerg     /// model, produces an ADDIS8 instruction that adds the GOT base
36906f32e7eSjoerg     /// register to sym\@got\@tlsld\@ha.
37006f32e7eSjoerg     ADDIS_TLSLD_HA,
37106f32e7eSjoerg 
37206f32e7eSjoerg     /// %x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS
37306f32e7eSjoerg     /// model, produces an ADDI8 instruction that adds G8RReg to
37406f32e7eSjoerg     /// sym\@got\@tlsld\@l and stores the result in X3.  Hidden by
37506f32e7eSjoerg     /// ADDIS_TLSLD_L_ADDR until after register assignment.
37606f32e7eSjoerg     ADDI_TLSLD_L,
37706f32e7eSjoerg 
37806f32e7eSjoerg     /// %x3 = GET_TLSLD_ADDR %x3, Symbol - For the local-dynamic TLS
37906f32e7eSjoerg     /// model, produces a call to __tls_get_addr(sym\@tlsld).  Hidden by
38006f32e7eSjoerg     /// ADDIS_TLSLD_L_ADDR until after register assignment.
38106f32e7eSjoerg     GET_TLSLD_ADDR,
38206f32e7eSjoerg 
38306f32e7eSjoerg     /// G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that
38406f32e7eSjoerg     /// combines ADDI_TLSLD_L and GET_TLSLD_ADDR until expansion
38506f32e7eSjoerg     /// following register assignment.
38606f32e7eSjoerg     ADDI_TLSLD_L_ADDR,
38706f32e7eSjoerg 
38806f32e7eSjoerg     /// G8RC = ADDIS_DTPREL_HA %x3, Symbol - For the local-dynamic TLS
38906f32e7eSjoerg     /// model, produces an ADDIS8 instruction that adds X3 to
39006f32e7eSjoerg     /// sym\@dtprel\@ha.
39106f32e7eSjoerg     ADDIS_DTPREL_HA,
39206f32e7eSjoerg 
39306f32e7eSjoerg     /// G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS
39406f32e7eSjoerg     /// model, produces an ADDI8 instruction that adds G8RReg to
39506f32e7eSjoerg     /// sym\@got\@dtprel\@l.
39606f32e7eSjoerg     ADDI_DTPREL_L,
39706f32e7eSjoerg 
398*da58b97aSjoerg     /// G8RC = PADDI_DTPREL %x3, Symbol - For the pc-rel based local-dynamic TLS
399*da58b97aSjoerg     /// model, produces a PADDI8 instruction that adds X3 to sym\@dtprel.
400*da58b97aSjoerg     PADDI_DTPREL,
401*da58b97aSjoerg 
40206f32e7eSjoerg     /// VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded
40306f32e7eSjoerg     /// during instruction selection to optimize a BUILD_VECTOR into
40406f32e7eSjoerg     /// operations on splats.  This is necessary to avoid losing these
40506f32e7eSjoerg     /// optimizations due to constant folding.
40606f32e7eSjoerg     VADD_SPLAT,
40706f32e7eSjoerg 
40806f32e7eSjoerg     /// CHAIN = SC CHAIN, Imm128 - System call.  The 7-bit unsigned
40906f32e7eSjoerg     /// operand identifies the operating system entry point.
41006f32e7eSjoerg     SC,
41106f32e7eSjoerg 
41206f32e7eSjoerg     /// CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
41306f32e7eSjoerg     CLRBHRB,
41406f32e7eSjoerg 
41506f32e7eSjoerg     /// GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch
41606f32e7eSjoerg     /// history rolling buffer entry.
41706f32e7eSjoerg     MFBHRBE,
41806f32e7eSjoerg 
41906f32e7eSjoerg     /// CHAIN = RFEBB CHAIN, State - Return from event-based branch.
42006f32e7eSjoerg     RFEBB,
42106f32e7eSjoerg 
42206f32e7eSjoerg     /// VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little
42306f32e7eSjoerg     /// endian.  Maps to an xxswapd instruction that corrects an lxvd2x
42406f32e7eSjoerg     /// or stxvd2x instruction.  The chain is necessary because the
42506f32e7eSjoerg     /// sequence replaces a load and needs to provide the same number
42606f32e7eSjoerg     /// of outputs.
42706f32e7eSjoerg     XXSWAPD,
42806f32e7eSjoerg 
42906f32e7eSjoerg     /// An SDNode for swaps that are not associated with any loads/stores
43006f32e7eSjoerg     /// and thereby have no chain.
43106f32e7eSjoerg     SWAP_NO_CHAIN,
43206f32e7eSjoerg 
43306f32e7eSjoerg     /// An SDNode for Power9 vector absolute value difference.
43406f32e7eSjoerg     /// operand #0 vector
43506f32e7eSjoerg     /// operand #1 vector
43606f32e7eSjoerg     /// operand #2 constant i32 0 or 1, to indicate whether needs to patch
43706f32e7eSjoerg     /// the most significant bit for signed i32
43806f32e7eSjoerg     ///
43906f32e7eSjoerg     /// Power9 VABSD* instructions are designed to support unsigned integer
44006f32e7eSjoerg     /// vectors (byte/halfword/word), if we want to make use of them for signed
44106f32e7eSjoerg     /// integer vectors, we have to flip their sign bits first. To flip sign bit
44206f32e7eSjoerg     /// for byte/halfword integer vector would become inefficient, but for word
44306f32e7eSjoerg     /// integer vector, we can leverage XVNEGSP to make it efficiently. eg:
44406f32e7eSjoerg     /// abs(sub(a,b)) => VABSDUW(a+0x80000000, b+0x80000000)
44506f32e7eSjoerg     ///               => VABSDUW((XVNEGSP a), (XVNEGSP b))
44606f32e7eSjoerg     VABSD,
44706f32e7eSjoerg 
44806f32e7eSjoerg     /// FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or
44906f32e7eSjoerg     /// lower (IDX=1) half of v4f32 to v2f64.
45006f32e7eSjoerg     FP_EXTEND_HALF,
45106f32e7eSjoerg 
452*da58b97aSjoerg     /// MAT_PCREL_ADDR = Materialize a PC Relative address. This can be done
453*da58b97aSjoerg     /// either through an add like PADDI or through a PC Relative load like
454*da58b97aSjoerg     /// PLD.
455*da58b97aSjoerg     MAT_PCREL_ADDR,
456*da58b97aSjoerg 
457*da58b97aSjoerg     /// TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for
458*da58b97aSjoerg     /// TLS global address when using dynamic access models. This can be done
459*da58b97aSjoerg     /// through an add like PADDI.
460*da58b97aSjoerg     TLS_DYNAMIC_MAT_PCREL_ADDR,
461*da58b97aSjoerg 
462*da58b97aSjoerg     /// TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address
463*da58b97aSjoerg     /// when using local exec access models, and when prefixed instructions are
464*da58b97aSjoerg     /// available. This is used with ADD_TLS to produce an add like PADDI.
465*da58b97aSjoerg     TLS_LOCAL_EXEC_MAT_ADDR,
466*da58b97aSjoerg 
467*da58b97aSjoerg     /// ACC_BUILD = Build an accumulator register from 4 VSX registers.
468*da58b97aSjoerg     ACC_BUILD,
469*da58b97aSjoerg 
470*da58b97aSjoerg     /// PAIR_BUILD = Build a vector pair register from 2 VSX registers.
471*da58b97aSjoerg     PAIR_BUILD,
472*da58b97aSjoerg 
473*da58b97aSjoerg     /// EXTRACT_VSX_REG = Extract one of the underlying vsx registers of
474*da58b97aSjoerg     /// an accumulator or pair register. This node is needed because
475*da58b97aSjoerg     /// EXTRACT_SUBVECTOR expects the input and output vectors to have the same
476*da58b97aSjoerg     /// element type.
477*da58b97aSjoerg     EXTRACT_VSX_REG,
478*da58b97aSjoerg 
479*da58b97aSjoerg     /// XXMFACC = This corresponds to the xxmfacc instruction.
480*da58b97aSjoerg     XXMFACC,
481*da58b97aSjoerg 
482*da58b97aSjoerg     // Constrained conversion from floating point to int
483*da58b97aSjoerg     STRICT_FCTIDZ = ISD::FIRST_TARGET_STRICTFP_OPCODE,
484*da58b97aSjoerg     STRICT_FCTIWZ,
485*da58b97aSjoerg     STRICT_FCTIDUZ,
486*da58b97aSjoerg     STRICT_FCTIWUZ,
487*da58b97aSjoerg 
488*da58b97aSjoerg     /// Constrained integer-to-floating-point conversion instructions.
489*da58b97aSjoerg     STRICT_FCFID,
490*da58b97aSjoerg     STRICT_FCFIDU,
491*da58b97aSjoerg     STRICT_FCFIDS,
492*da58b97aSjoerg     STRICT_FCFIDUS,
493*da58b97aSjoerg 
494*da58b97aSjoerg     /// Constrained floating point add in round-to-zero mode.
495*da58b97aSjoerg     STRICT_FADDRTZ,
496*da58b97aSjoerg 
49706f32e7eSjoerg     /// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a
49806f32e7eSjoerg     /// byte-swapping store instruction.  It byte-swaps the low "Type" bits of
49906f32e7eSjoerg     /// the GPRC input, then stores it through Ptr.  Type can be either i16 or
50006f32e7eSjoerg     /// i32.
50106f32e7eSjoerg     STBRX = ISD::FIRST_TARGET_MEMORY_OPCODE,
50206f32e7eSjoerg 
50306f32e7eSjoerg     /// GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a
50406f32e7eSjoerg     /// byte-swapping load instruction.  It loads "Type" bits, byte swaps it,
50506f32e7eSjoerg     /// then puts it in the bottom bits of the GPRC.  TYPE can be either i16
50606f32e7eSjoerg     /// or i32.
50706f32e7eSjoerg     LBRX,
50806f32e7eSjoerg 
50906f32e7eSjoerg     /// STFIWX - The STFIWX instruction.  The first operand is an input token
51006f32e7eSjoerg     /// chain, then an f64 value to store, then an address to store it to.
51106f32e7eSjoerg     STFIWX,
51206f32e7eSjoerg 
51306f32e7eSjoerg     /// GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point
51406f32e7eSjoerg     /// load which sign-extends from a 32-bit integer value into the
51506f32e7eSjoerg     /// destination 64-bit register.
51606f32e7eSjoerg     LFIWAX,
51706f32e7eSjoerg 
51806f32e7eSjoerg     /// GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point
51906f32e7eSjoerg     /// load which zero-extends from a 32-bit integer value into the
52006f32e7eSjoerg     /// destination 64-bit register.
52106f32e7eSjoerg     LFIWZX,
52206f32e7eSjoerg 
52306f32e7eSjoerg     /// GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an
52406f32e7eSjoerg     /// integer smaller than 64 bits into a VSR. The integer is zero-extended.
52506f32e7eSjoerg     /// This can be used for converting loaded integers to floating point.
52606f32e7eSjoerg     LXSIZX,
52706f32e7eSjoerg 
52806f32e7eSjoerg     /// STXSIX - The STXSI[bh]X instruction. The first operand is an input
52906f32e7eSjoerg     /// chain, then an f64 value to store, then an address to store it to,
53006f32e7eSjoerg     /// followed by a byte-width for the store.
53106f32e7eSjoerg     STXSIX,
53206f32e7eSjoerg 
53306f32e7eSjoerg     /// VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
53406f32e7eSjoerg     /// Maps directly to an lxvd2x instruction that will be followed by
53506f32e7eSjoerg     /// an xxswapd.
53606f32e7eSjoerg     LXVD2X,
53706f32e7eSjoerg 
538*da58b97aSjoerg     /// LXVRZX - Load VSX Vector Rightmost and Zero Extend
539*da58b97aSjoerg     /// This node represents v1i128 BUILD_VECTOR of a zero extending load
540*da58b97aSjoerg     /// instruction from <byte, halfword, word, or doubleword> to i128.
541*da58b97aSjoerg     /// Allows utilization of the Load VSX Vector Rightmost Instructions.
542*da58b97aSjoerg     LXVRZX,
543*da58b97aSjoerg 
54406f32e7eSjoerg     /// VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
54506f32e7eSjoerg     /// Maps directly to one of lxvd2x/lxvw4x/lxvh8x/lxvb16x depending on
54606f32e7eSjoerg     /// the vector type to load vector in big-endian element order.
54706f32e7eSjoerg     LOAD_VEC_BE,
54806f32e7eSjoerg 
54906f32e7eSjoerg     /// VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a
55006f32e7eSjoerg     /// v2f32 value into the lower half of a VSR register.
55106f32e7eSjoerg     LD_VSX_LH,
55206f32e7eSjoerg 
55306f32e7eSjoerg     /// VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory
55406f32e7eSjoerg     /// instructions such as LXVDSX, LXVWSX.
55506f32e7eSjoerg     LD_SPLAT,
55606f32e7eSjoerg 
55706f32e7eSjoerg     /// CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
55806f32e7eSjoerg     /// Maps directly to an stxvd2x instruction that will be preceded by
55906f32e7eSjoerg     /// an xxswapd.
56006f32e7eSjoerg     STXVD2X,
56106f32e7eSjoerg 
56206f32e7eSjoerg     /// CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
56306f32e7eSjoerg     /// Maps directly to one of stxvd2x/stxvw4x/stxvh8x/stxvb16x depending on
56406f32e7eSjoerg     /// the vector type to store vector in big-endian element order.
56506f32e7eSjoerg     STORE_VEC_BE,
56606f32e7eSjoerg 
56706f32e7eSjoerg     /// Store scalar integers from VSR.
56806f32e7eSjoerg     ST_VSR_SCAL_INT,
56906f32e7eSjoerg 
57006f32e7eSjoerg     /// ATOMIC_CMP_SWAP - the exact same as the target-independent nodes
57106f32e7eSjoerg     /// except they ensure that the compare input is zero-extended for
57206f32e7eSjoerg     /// sub-word versions because the atomic loads zero-extend.
573*da58b97aSjoerg     ATOMIC_CMP_SWAP_8,
574*da58b97aSjoerg     ATOMIC_CMP_SWAP_16,
57506f32e7eSjoerg 
57606f32e7eSjoerg     /// GPRC = TOC_ENTRY GA, TOC
57706f32e7eSjoerg     /// Loads the entry for GA from the TOC, where the TOC base is given by
57806f32e7eSjoerg     /// the last operand.
57906f32e7eSjoerg     TOC_ENTRY
58006f32e7eSjoerg   };
58106f32e7eSjoerg 
58206f32e7eSjoerg   } // end namespace PPCISD
58306f32e7eSjoerg 
58406f32e7eSjoerg   /// Define some predicates that are used for node matching.
58506f32e7eSjoerg   namespace PPC {
58606f32e7eSjoerg 
58706f32e7eSjoerg     /// isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a
58806f32e7eSjoerg     /// VPKUHUM instruction.
58906f32e7eSjoerg     bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
59006f32e7eSjoerg                               SelectionDAG &DAG);
59106f32e7eSjoerg 
59206f32e7eSjoerg     /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
59306f32e7eSjoerg     /// VPKUWUM instruction.
59406f32e7eSjoerg     bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
59506f32e7eSjoerg                               SelectionDAG &DAG);
59606f32e7eSjoerg 
59706f32e7eSjoerg     /// isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a
59806f32e7eSjoerg     /// VPKUDUM instruction.
59906f32e7eSjoerg     bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind,
60006f32e7eSjoerg                               SelectionDAG &DAG);
60106f32e7eSjoerg 
60206f32e7eSjoerg     /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
60306f32e7eSjoerg     /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
60406f32e7eSjoerg     bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,
60506f32e7eSjoerg                             unsigned ShuffleKind, SelectionDAG &DAG);
60606f32e7eSjoerg 
60706f32e7eSjoerg     /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
60806f32e7eSjoerg     /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).
60906f32e7eSjoerg     bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize,
61006f32e7eSjoerg                             unsigned ShuffleKind, SelectionDAG &DAG);
61106f32e7eSjoerg 
61206f32e7eSjoerg     /// isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for
61306f32e7eSjoerg     /// a VMRGEW or VMRGOW instruction
61406f32e7eSjoerg     bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven,
61506f32e7eSjoerg                              unsigned ShuffleKind, SelectionDAG &DAG);
61606f32e7eSjoerg     /// isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable
61706f32e7eSjoerg     /// for a XXSLDWI instruction.
61806f32e7eSjoerg     bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
61906f32e7eSjoerg                               bool &Swap, bool IsLE);
62006f32e7eSjoerg 
62106f32e7eSjoerg     /// isXXBRHShuffleMask - Return true if this is a shuffle mask suitable
62206f32e7eSjoerg     /// for a XXBRH instruction.
62306f32e7eSjoerg     bool isXXBRHShuffleMask(ShuffleVectorSDNode *N);
62406f32e7eSjoerg 
62506f32e7eSjoerg     /// isXXBRWShuffleMask - Return true if this is a shuffle mask suitable
62606f32e7eSjoerg     /// for a XXBRW instruction.
62706f32e7eSjoerg     bool isXXBRWShuffleMask(ShuffleVectorSDNode *N);
62806f32e7eSjoerg 
62906f32e7eSjoerg     /// isXXBRDShuffleMask - Return true if this is a shuffle mask suitable
63006f32e7eSjoerg     /// for a XXBRD instruction.
63106f32e7eSjoerg     bool isXXBRDShuffleMask(ShuffleVectorSDNode *N);
63206f32e7eSjoerg 
63306f32e7eSjoerg     /// isXXBRQShuffleMask - Return true if this is a shuffle mask suitable
63406f32e7eSjoerg     /// for a XXBRQ instruction.
63506f32e7eSjoerg     bool isXXBRQShuffleMask(ShuffleVectorSDNode *N);
63606f32e7eSjoerg 
63706f32e7eSjoerg     /// isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable
63806f32e7eSjoerg     /// for a XXPERMDI instruction.
63906f32e7eSjoerg     bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
64006f32e7eSjoerg                               bool &Swap, bool IsLE);
64106f32e7eSjoerg 
64206f32e7eSjoerg     /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the
64306f32e7eSjoerg     /// shift amount, otherwise return -1.
64406f32e7eSjoerg     int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind,
64506f32e7eSjoerg                             SelectionDAG &DAG);
64606f32e7eSjoerg 
64706f32e7eSjoerg     /// isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand
64806f32e7eSjoerg     /// specifies a splat of a single element that is suitable for input to
64906f32e7eSjoerg     /// VSPLTB/VSPLTH/VSPLTW.
65006f32e7eSjoerg     bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize);
65106f32e7eSjoerg 
65206f32e7eSjoerg     /// isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by
65306f32e7eSjoerg     /// the XXINSERTW instruction introduced in ISA 3.0. This is essentially any
65406f32e7eSjoerg     /// shuffle of v4f32/v4i32 vectors that just inserts one element from one
65506f32e7eSjoerg     /// vector into the other. This function will also set a couple of
65606f32e7eSjoerg     /// output parameters for how much the source vector needs to be shifted and
65706f32e7eSjoerg     /// what byte number needs to be specified for the instruction to put the
65806f32e7eSjoerg     /// element in the desired location of the target vector.
65906f32e7eSjoerg     bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,
66006f32e7eSjoerg                          unsigned &InsertAtByte, bool &Swap, bool IsLE);
66106f32e7eSjoerg 
66206f32e7eSjoerg     /// getSplatIdxForPPCMnemonics - Return the splat index as a value that is
66306f32e7eSjoerg     /// appropriate for PPC mnemonics (which have a big endian bias - namely
66406f32e7eSjoerg     /// elements are counted from the left of the vector register).
66506f32e7eSjoerg     unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize,
66606f32e7eSjoerg                                         SelectionDAG &DAG);
66706f32e7eSjoerg 
66806f32e7eSjoerg     /// get_VSPLTI_elt - If this is a build_vector of constants which can be
66906f32e7eSjoerg     /// formed by using a vspltis[bhw] instruction of the specified element
67006f32e7eSjoerg     /// size, return the constant being splatted.  The ByteSize field indicates
67106f32e7eSjoerg     /// the number of bytes of each element [124] -> [bhw].
67206f32e7eSjoerg     SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);
67306f32e7eSjoerg 
674*da58b97aSjoerg     // Flags for computing the optimal addressing mode for loads and stores.
675*da58b97aSjoerg     enum MemOpFlags {
676*da58b97aSjoerg       MOF_None = 0,
67706f32e7eSjoerg 
678*da58b97aSjoerg       // Extension mode for integer loads.
679*da58b97aSjoerg       MOF_SExt = 1,
680*da58b97aSjoerg       MOF_ZExt = 1 << 1,
681*da58b97aSjoerg       MOF_NoExt = 1 << 2,
682*da58b97aSjoerg 
683*da58b97aSjoerg       // Address computation flags.
684*da58b97aSjoerg       MOF_NotAddNorCst = 1 << 5,      // Not const. or sum of ptr and scalar.
685*da58b97aSjoerg       MOF_RPlusSImm16 = 1 << 6,       // Reg plus signed 16-bit constant.
686*da58b97aSjoerg       MOF_RPlusLo = 1 << 7,           // Reg plus signed 16-bit relocation
687*da58b97aSjoerg       MOF_RPlusSImm16Mult4 = 1 << 8,  // Reg plus 16-bit signed multiple of 4.
688*da58b97aSjoerg       MOF_RPlusSImm16Mult16 = 1 << 9, // Reg plus 16-bit signed multiple of 16.
689*da58b97aSjoerg       MOF_RPlusSImm34 = 1 << 10,      // Reg plus 34-bit signed constant.
690*da58b97aSjoerg       MOF_RPlusR = 1 << 11,           // Sum of two variables.
691*da58b97aSjoerg       MOF_PCRel = 1 << 12,            // PC-Relative relocation.
692*da58b97aSjoerg       MOF_AddrIsSImm32 = 1 << 13,     // A simple 32-bit constant.
693*da58b97aSjoerg 
694*da58b97aSjoerg       // The in-memory type.
695*da58b97aSjoerg       MOF_SubWordInt = 1 << 15,
696*da58b97aSjoerg       MOF_WordInt = 1 << 16,
697*da58b97aSjoerg       MOF_DoubleWordInt = 1 << 17,
698*da58b97aSjoerg       MOF_ScalarFloat = 1 << 18, // Scalar single or double precision.
699*da58b97aSjoerg       MOF_Vector = 1 << 19,      // Vector types and quad precision scalars.
700*da58b97aSjoerg       MOF_Vector256 = 1 << 20,
701*da58b97aSjoerg 
702*da58b97aSjoerg       // Subtarget features.
703*da58b97aSjoerg       MOF_SubtargetBeforeP9 = 1 << 22,
704*da58b97aSjoerg       MOF_SubtargetP9 = 1 << 23,
705*da58b97aSjoerg       MOF_SubtargetP10 = 1 << 24,
706*da58b97aSjoerg       MOF_SubtargetSPE = 1 << 25
707*da58b97aSjoerg     };
708*da58b97aSjoerg 
709*da58b97aSjoerg     // The addressing modes for loads and stores.
710*da58b97aSjoerg     enum AddrMode {
711*da58b97aSjoerg       AM_None,
712*da58b97aSjoerg       AM_DForm,
713*da58b97aSjoerg       AM_DSForm,
714*da58b97aSjoerg       AM_DQForm,
715*da58b97aSjoerg       AM_XForm,
716*da58b97aSjoerg     };
71706f32e7eSjoerg   } // end namespace PPC
71806f32e7eSjoerg 
71906f32e7eSjoerg   class PPCTargetLowering : public TargetLowering {
72006f32e7eSjoerg     const PPCSubtarget &Subtarget;
72106f32e7eSjoerg 
72206f32e7eSjoerg   public:
72306f32e7eSjoerg     explicit PPCTargetLowering(const PPCTargetMachine &TM,
72406f32e7eSjoerg                                const PPCSubtarget &STI);
72506f32e7eSjoerg 
72606f32e7eSjoerg     /// getTargetNodeName() - This method returns the name of a target specific
72706f32e7eSjoerg     /// DAG node.
72806f32e7eSjoerg     const char *getTargetNodeName(unsigned Opcode) const override;
72906f32e7eSjoerg 
isSelectSupported(SelectSupportKind Kind)73006f32e7eSjoerg     bool isSelectSupported(SelectSupportKind Kind) const override {
73106f32e7eSjoerg       // PowerPC does not support scalar condition selects on vectors.
73206f32e7eSjoerg       return (Kind != SelectSupportKind::ScalarCondVectorVal);
73306f32e7eSjoerg     }
73406f32e7eSjoerg 
73506f32e7eSjoerg     /// getPreferredVectorAction - The code we generate when vector types are
73606f32e7eSjoerg     /// legalized by promoting the integer element type is often much worse
73706f32e7eSjoerg     /// than code we generate if we widen the type for applicable vector types.
73806f32e7eSjoerg     /// The issue with promoting is that the vector is scalaraized, individual
73906f32e7eSjoerg     /// elements promoted and then the vector is rebuilt. So say we load a pair
74006f32e7eSjoerg     /// of v4i8's and shuffle them. This will turn into a mess of 8 extending
74106f32e7eSjoerg     /// loads, moves back into VSR's (or memory ops if we don't have moves) and
74206f32e7eSjoerg     /// then the VPERM for the shuffle. All in all a very slow sequence.
getPreferredVectorAction(MVT VT)74306f32e7eSjoerg     TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT)
74406f32e7eSjoerg       const override {
745*da58b97aSjoerg       if (!VT.isScalableVector() && VT.getVectorNumElements() != 1 &&
746*da58b97aSjoerg           VT.getScalarSizeInBits() % 8 == 0)
74706f32e7eSjoerg         return TypeWidenVector;
74806f32e7eSjoerg       return TargetLoweringBase::getPreferredVectorAction(VT);
74906f32e7eSjoerg     }
75006f32e7eSjoerg 
75106f32e7eSjoerg     bool useSoftFloat() const override;
75206f32e7eSjoerg 
75306f32e7eSjoerg     bool hasSPE() const;
75406f32e7eSjoerg 
getScalarShiftAmountTy(const DataLayout &,EVT)75506f32e7eSjoerg     MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
75606f32e7eSjoerg       return MVT::i32;
75706f32e7eSjoerg     }
75806f32e7eSjoerg 
isCheapToSpeculateCttz()75906f32e7eSjoerg     bool isCheapToSpeculateCttz() const override {
76006f32e7eSjoerg       return true;
76106f32e7eSjoerg     }
76206f32e7eSjoerg 
isCheapToSpeculateCtlz()76306f32e7eSjoerg     bool isCheapToSpeculateCtlz() const override {
76406f32e7eSjoerg       return true;
76506f32e7eSjoerg     }
76606f32e7eSjoerg 
isCtlzFast()76706f32e7eSjoerg     bool isCtlzFast() const override {
76806f32e7eSjoerg       return true;
76906f32e7eSjoerg     }
77006f32e7eSjoerg 
isEqualityCmpFoldedWithSignedCmp()771*da58b97aSjoerg     bool isEqualityCmpFoldedWithSignedCmp() const override {
772*da58b97aSjoerg       return false;
773*da58b97aSjoerg     }
774*da58b97aSjoerg 
hasAndNotCompare(SDValue)77506f32e7eSjoerg     bool hasAndNotCompare(SDValue) const override {
77606f32e7eSjoerg       return true;
77706f32e7eSjoerg     }
77806f32e7eSjoerg 
77906f32e7eSjoerg     bool preferIncOfAddToSubOfNot(EVT VT) const override;
78006f32e7eSjoerg 
convertSetCCLogicToBitwiseLogic(EVT VT)78106f32e7eSjoerg     bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
78206f32e7eSjoerg       return VT.isScalarInteger();
78306f32e7eSjoerg     }
78406f32e7eSjoerg 
785*da58b97aSjoerg     SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps,
786*da58b97aSjoerg                                  bool OptForSize, NegatibleCost &Cost,
787*da58b97aSjoerg                                  unsigned Depth = 0) const override;
78806f32e7eSjoerg 
78906f32e7eSjoerg     /// getSetCCResultType - Return the ISD::SETCC ValueType
79006f32e7eSjoerg     EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
79106f32e7eSjoerg                            EVT VT) const override;
79206f32e7eSjoerg 
793*da58b97aSjoerg     /// Return true if target always benefits from combining into FMA for a
79406f32e7eSjoerg     /// given value type. This must typically return false on targets where FMA
79506f32e7eSjoerg     /// takes more cycles to execute than FADD.
79606f32e7eSjoerg     bool enableAggressiveFMAFusion(EVT VT) const override;
79706f32e7eSjoerg 
79806f32e7eSjoerg     /// getPreIndexedAddressParts - returns true by value, base pointer and
79906f32e7eSjoerg     /// offset pointer and addressing mode by reference if the node's address
80006f32e7eSjoerg     /// can be legally represented as pre-indexed load / store address.
80106f32e7eSjoerg     bool getPreIndexedAddressParts(SDNode *N, SDValue &Base,
80206f32e7eSjoerg                                    SDValue &Offset,
80306f32e7eSjoerg                                    ISD::MemIndexedMode &AM,
80406f32e7eSjoerg                                    SelectionDAG &DAG) const override;
80506f32e7eSjoerg 
80606f32e7eSjoerg     /// SelectAddressEVXRegReg - Given the specified addressed, check to see if
80706f32e7eSjoerg     /// it can be more efficiently represented as [r+imm].
80806f32e7eSjoerg     bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index,
80906f32e7eSjoerg                                 SelectionDAG &DAG) const;
81006f32e7eSjoerg 
81106f32e7eSjoerg     /// SelectAddressRegReg - Given the specified addressed, check to see if it
81206f32e7eSjoerg     /// can be more efficiently represented as [r+imm]. If \p EncodingAlignment
81306f32e7eSjoerg     /// is non-zero, only accept displacement which is not suitable for [r+imm].
81406f32e7eSjoerg     /// Returns false if it can be represented by [r+imm], which are preferred.
81506f32e7eSjoerg     bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index,
81606f32e7eSjoerg                              SelectionDAG &DAG,
817*da58b97aSjoerg                              MaybeAlign EncodingAlignment = None) const;
81806f32e7eSjoerg 
81906f32e7eSjoerg     /// SelectAddressRegImm - Returns true if the address N can be represented
82006f32e7eSjoerg     /// by a base register plus a signed 16-bit displacement [r+imm], and if it
82106f32e7eSjoerg     /// is not better represented as reg+reg. If \p EncodingAlignment is
82206f32e7eSjoerg     /// non-zero, only accept displacements suitable for instruction encoding
82306f32e7eSjoerg     /// requirement, i.e. multiples of 4 for DS form.
82406f32e7eSjoerg     bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base,
82506f32e7eSjoerg                              SelectionDAG &DAG,
826*da58b97aSjoerg                              MaybeAlign EncodingAlignment) const;
827*da58b97aSjoerg     bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base,
828*da58b97aSjoerg                                SelectionDAG &DAG) const;
82906f32e7eSjoerg 
83006f32e7eSjoerg     /// SelectAddressRegRegOnly - Given the specified addressed, force it to be
83106f32e7eSjoerg     /// represented as an indexed [r+r] operation.
83206f32e7eSjoerg     bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index,
83306f32e7eSjoerg                                  SelectionDAG &DAG) const;
83406f32e7eSjoerg 
835*da58b97aSjoerg     /// SelectAddressPCRel - Represent the specified address as pc relative to
836*da58b97aSjoerg     /// be represented as [pc+imm]
837*da58b97aSjoerg     bool SelectAddressPCRel(SDValue N, SDValue &Base) const;
838*da58b97aSjoerg 
83906f32e7eSjoerg     Sched::Preference getSchedulingPreference(SDNode *N) const override;
84006f32e7eSjoerg 
84106f32e7eSjoerg     /// LowerOperation - Provide custom lowering hooks for some operations.
84206f32e7eSjoerg     ///
84306f32e7eSjoerg     SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
84406f32e7eSjoerg 
84506f32e7eSjoerg     /// ReplaceNodeResults - Replace the results of node with an illegal result
84606f32e7eSjoerg     /// type with new values built out of custom code.
84706f32e7eSjoerg     ///
84806f32e7eSjoerg     void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
84906f32e7eSjoerg                             SelectionDAG &DAG) const override;
85006f32e7eSjoerg 
85106f32e7eSjoerg     SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const;
85206f32e7eSjoerg     SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const;
85306f32e7eSjoerg 
85406f32e7eSjoerg     SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
85506f32e7eSjoerg 
85606f32e7eSjoerg     SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG,
85706f32e7eSjoerg                           SmallVectorImpl<SDNode *> &Created) const override;
85806f32e7eSjoerg 
859*da58b97aSjoerg     Register getRegisterByName(const char* RegName, LLT VT,
86006f32e7eSjoerg                                const MachineFunction &MF) const override;
86106f32e7eSjoerg 
86206f32e7eSjoerg     void computeKnownBitsForTargetNode(const SDValue Op,
86306f32e7eSjoerg                                        KnownBits &Known,
86406f32e7eSjoerg                                        const APInt &DemandedElts,
86506f32e7eSjoerg                                        const SelectionDAG &DAG,
86606f32e7eSjoerg                                        unsigned Depth = 0) const override;
86706f32e7eSjoerg 
86806f32e7eSjoerg     Align getPrefLoopAlignment(MachineLoop *ML) const override;
86906f32e7eSjoerg 
shouldInsertFencesForAtomic(const Instruction * I)87006f32e7eSjoerg     bool shouldInsertFencesForAtomic(const Instruction *I) const override {
87106f32e7eSjoerg       return true;
87206f32e7eSjoerg     }
87306f32e7eSjoerg 
87406f32e7eSjoerg     Instruction *emitLeadingFence(IRBuilder<> &Builder, Instruction *Inst,
87506f32e7eSjoerg                                   AtomicOrdering Ord) const override;
87606f32e7eSjoerg     Instruction *emitTrailingFence(IRBuilder<> &Builder, Instruction *Inst,
87706f32e7eSjoerg                                    AtomicOrdering Ord) const override;
87806f32e7eSjoerg 
87906f32e7eSjoerg     MachineBasicBlock *
88006f32e7eSjoerg     EmitInstrWithCustomInserter(MachineInstr &MI,
88106f32e7eSjoerg                                 MachineBasicBlock *MBB) const override;
88206f32e7eSjoerg     MachineBasicBlock *EmitAtomicBinary(MachineInstr &MI,
88306f32e7eSjoerg                                         MachineBasicBlock *MBB,
88406f32e7eSjoerg                                         unsigned AtomicSize,
88506f32e7eSjoerg                                         unsigned BinOpcode,
88606f32e7eSjoerg                                         unsigned CmpOpcode = 0,
88706f32e7eSjoerg                                         unsigned CmpPred = 0) const;
88806f32e7eSjoerg     MachineBasicBlock *EmitPartwordAtomicBinary(MachineInstr &MI,
88906f32e7eSjoerg                                                 MachineBasicBlock *MBB,
89006f32e7eSjoerg                                                 bool is8bit,
89106f32e7eSjoerg                                                 unsigned Opcode,
89206f32e7eSjoerg                                                 unsigned CmpOpcode = 0,
89306f32e7eSjoerg                                                 unsigned CmpPred = 0) const;
89406f32e7eSjoerg 
89506f32e7eSjoerg     MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
89606f32e7eSjoerg                                         MachineBasicBlock *MBB) const;
89706f32e7eSjoerg 
89806f32e7eSjoerg     MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
89906f32e7eSjoerg                                          MachineBasicBlock *MBB) const;
90006f32e7eSjoerg 
901*da58b97aSjoerg     MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,
902*da58b97aSjoerg                                         MachineBasicBlock *MBB) const;
903*da58b97aSjoerg 
904*da58b97aSjoerg     bool hasInlineStackProbe(MachineFunction &MF) const override;
905*da58b97aSjoerg 
906*da58b97aSjoerg     unsigned getStackProbeSize(MachineFunction &MF) const;
907*da58b97aSjoerg 
90806f32e7eSjoerg     ConstraintType getConstraintType(StringRef Constraint) const override;
90906f32e7eSjoerg 
91006f32e7eSjoerg     /// Examine constraint string and operand type and determine a weight value.
91106f32e7eSjoerg     /// The operand object must already have been set up with the operand type.
91206f32e7eSjoerg     ConstraintWeight getSingleConstraintMatchWeight(
91306f32e7eSjoerg       AsmOperandInfo &info, const char *constraint) const override;
91406f32e7eSjoerg 
91506f32e7eSjoerg     std::pair<unsigned, const TargetRegisterClass *>
91606f32e7eSjoerg     getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
91706f32e7eSjoerg                                  StringRef Constraint, MVT VT) const override;
91806f32e7eSjoerg 
91906f32e7eSjoerg     /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
92006f32e7eSjoerg     /// function arguments in the caller parameter area.  This is the actual
92106f32e7eSjoerg     /// alignment, not its logarithm.
92206f32e7eSjoerg     unsigned getByValTypeAlignment(Type *Ty,
92306f32e7eSjoerg                                    const DataLayout &DL) const override;
92406f32e7eSjoerg 
92506f32e7eSjoerg     /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
92606f32e7eSjoerg     /// vector.  If it is invalid, don't add anything to Ops.
92706f32e7eSjoerg     void LowerAsmOperandForConstraint(SDValue Op,
92806f32e7eSjoerg                                       std::string &Constraint,
92906f32e7eSjoerg                                       std::vector<SDValue> &Ops,
93006f32e7eSjoerg                                       SelectionDAG &DAG) const override;
93106f32e7eSjoerg 
93206f32e7eSjoerg     unsigned
getInlineAsmMemConstraint(StringRef ConstraintCode)93306f32e7eSjoerg     getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
93406f32e7eSjoerg       if (ConstraintCode == "es")
93506f32e7eSjoerg         return InlineAsm::Constraint_es;
93606f32e7eSjoerg       else if (ConstraintCode == "Q")
93706f32e7eSjoerg         return InlineAsm::Constraint_Q;
93806f32e7eSjoerg       else if (ConstraintCode == "Z")
93906f32e7eSjoerg         return InlineAsm::Constraint_Z;
94006f32e7eSjoerg       else if (ConstraintCode == "Zy")
94106f32e7eSjoerg         return InlineAsm::Constraint_Zy;
94206f32e7eSjoerg       return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
94306f32e7eSjoerg     }
94406f32e7eSjoerg 
94506f32e7eSjoerg     /// isLegalAddressingMode - Return true if the addressing mode represented
94606f32e7eSjoerg     /// by AM is legal for this target, for a load/store of the specified type.
94706f32e7eSjoerg     bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
94806f32e7eSjoerg                                Type *Ty, unsigned AS,
94906f32e7eSjoerg                                Instruction *I = nullptr) const override;
95006f32e7eSjoerg 
95106f32e7eSjoerg     /// isLegalICmpImmediate - Return true if the specified immediate is legal
95206f32e7eSjoerg     /// icmp immediate, that is the target has icmp instructions which can
95306f32e7eSjoerg     /// compare a register against the immediate without having to materialize
95406f32e7eSjoerg     /// the immediate into a register.
95506f32e7eSjoerg     bool isLegalICmpImmediate(int64_t Imm) const override;
95606f32e7eSjoerg 
95706f32e7eSjoerg     /// isLegalAddImmediate - Return true if the specified immediate is legal
95806f32e7eSjoerg     /// add immediate, that is the target has add instructions which can
95906f32e7eSjoerg     /// add a register and the immediate without having to materialize
96006f32e7eSjoerg     /// the immediate into a register.
96106f32e7eSjoerg     bool isLegalAddImmediate(int64_t Imm) const override;
96206f32e7eSjoerg 
96306f32e7eSjoerg     /// isTruncateFree - Return true if it's free to truncate a value of
96406f32e7eSjoerg     /// type Ty1 to type Ty2. e.g. On PPC it's free to truncate a i64 value in
96506f32e7eSjoerg     /// register X1 to i32 by referencing its sub-register R1.
96606f32e7eSjoerg     bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
96706f32e7eSjoerg     bool isTruncateFree(EVT VT1, EVT VT2) const override;
96806f32e7eSjoerg 
96906f32e7eSjoerg     bool isZExtFree(SDValue Val, EVT VT2) const override;
97006f32e7eSjoerg 
97106f32e7eSjoerg     bool isFPExtFree(EVT DestVT, EVT SrcVT) const override;
97206f32e7eSjoerg 
97306f32e7eSjoerg     /// Returns true if it is beneficial to convert a load of a constant
97406f32e7eSjoerg     /// to just the constant itself.
97506f32e7eSjoerg     bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
97606f32e7eSjoerg                                            Type *Ty) const override;
97706f32e7eSjoerg 
convertSelectOfConstantsToMath(EVT VT)97806f32e7eSjoerg     bool convertSelectOfConstantsToMath(EVT VT) const override {
97906f32e7eSjoerg       return true;
98006f32e7eSjoerg     }
98106f32e7eSjoerg 
982*da58b97aSjoerg     bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
983*da58b97aSjoerg                                 SDValue C) const override;
984*da58b97aSjoerg 
isDesirableToTransformToIntegerOp(unsigned Opc,EVT VT)98506f32e7eSjoerg     bool isDesirableToTransformToIntegerOp(unsigned Opc,
98606f32e7eSjoerg                                            EVT VT) const override {
98706f32e7eSjoerg       // Only handle float load/store pair because float(fpr) load/store
98806f32e7eSjoerg       // instruction has more cycles than integer(gpr) load/store in PPC.
98906f32e7eSjoerg       if (Opc != ISD::LOAD && Opc != ISD::STORE)
99006f32e7eSjoerg         return false;
99106f32e7eSjoerg       if (VT != MVT::f32 && VT != MVT::f64)
99206f32e7eSjoerg         return false;
99306f32e7eSjoerg 
99406f32e7eSjoerg       return true;
99506f32e7eSjoerg     }
99606f32e7eSjoerg 
99706f32e7eSjoerg     // Returns true if the address of the global is stored in TOC entry.
99806f32e7eSjoerg     bool isAccessedAsGotIndirect(SDValue N) const;
99906f32e7eSjoerg 
100006f32e7eSjoerg     bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
100106f32e7eSjoerg 
100206f32e7eSjoerg     bool getTgtMemIntrinsic(IntrinsicInfo &Info,
100306f32e7eSjoerg                             const CallInst &I,
100406f32e7eSjoerg                             MachineFunction &MF,
100506f32e7eSjoerg                             unsigned Intrinsic) const override;
100606f32e7eSjoerg 
100706f32e7eSjoerg     /// It returns EVT::Other if the type should be determined using generic
100806f32e7eSjoerg     /// target-independent logic.
1009*da58b97aSjoerg     EVT getOptimalMemOpType(const MemOp &Op,
101006f32e7eSjoerg                             const AttributeList &FuncAttributes) const override;
101106f32e7eSjoerg 
101206f32e7eSjoerg     /// Is unaligned memory access allowed for the given type, and is it fast
101306f32e7eSjoerg     /// relative to software emulation.
101406f32e7eSjoerg     bool allowsMisalignedMemoryAccesses(
1015*da58b97aSjoerg         EVT VT, unsigned AddrSpace, Align Alignment = Align(1),
101606f32e7eSjoerg         MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
101706f32e7eSjoerg         bool *Fast = nullptr) const override;
101806f32e7eSjoerg 
101906f32e7eSjoerg     /// isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster
102006f32e7eSjoerg     /// than a pair of fmul and fadd instructions. fmuladd intrinsics will be
102106f32e7eSjoerg     /// expanded to FMAs when this method returns true, otherwise fmuladd is
102206f32e7eSjoerg     /// expanded to fmul + fadd.
1023*da58b97aSjoerg     bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
1024*da58b97aSjoerg                                     EVT VT) const override;
1025*da58b97aSjoerg 
1026*da58b97aSjoerg     bool isFMAFasterThanFMulAndFAdd(const Function &F, Type *Ty) const override;
1027*da58b97aSjoerg 
1028*da58b97aSjoerg     /// isProfitableToHoist - Check if it is profitable to hoist instruction
1029*da58b97aSjoerg     /// \p I to its dominator block.
1030*da58b97aSjoerg     /// For example, it is not profitable if \p I and it's only user can form a
1031*da58b97aSjoerg     /// FMA instruction, because Powerpc prefers FMADD.
1032*da58b97aSjoerg     bool isProfitableToHoist(Instruction *I) const override;
103306f32e7eSjoerg 
103406f32e7eSjoerg     const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
103506f32e7eSjoerg 
103606f32e7eSjoerg     // Should we expand the build vector with shuffles?
103706f32e7eSjoerg     bool
103806f32e7eSjoerg     shouldExpandBuildVectorWithShuffles(EVT VT,
103906f32e7eSjoerg                                         unsigned DefinedValues) const override;
104006f32e7eSjoerg 
1041*da58b97aSjoerg     // Keep the zero-extensions for arguments to libcalls.
shouldKeepZExtForFP16Conv()1042*da58b97aSjoerg     bool shouldKeepZExtForFP16Conv() const override { return true; }
1043*da58b97aSjoerg 
104406f32e7eSjoerg     /// createFastISel - This method returns a target-specific FastISel object,
104506f32e7eSjoerg     /// or null if the target does not support "fast" instruction selection.
104606f32e7eSjoerg     FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
104706f32e7eSjoerg                              const TargetLibraryInfo *LibInfo) const override;
104806f32e7eSjoerg 
104906f32e7eSjoerg     /// Returns true if an argument of type Ty needs to be passed in a
105006f32e7eSjoerg     /// contiguous block of registers in calling convention CallConv.
functionArgumentNeedsConsecutiveRegisters(Type * Ty,CallingConv::ID CallConv,bool isVarArg)105106f32e7eSjoerg     bool functionArgumentNeedsConsecutiveRegisters(
105206f32e7eSjoerg       Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override {
105306f32e7eSjoerg       // We support any array type as "consecutive" block in the parameter
105406f32e7eSjoerg       // save area.  The element type defines the alignment requirement and
105506f32e7eSjoerg       // whether the argument should go in GPRs, FPRs, or VRs if available.
105606f32e7eSjoerg       //
105706f32e7eSjoerg       // Note that clang uses this capability both to implement the ELFv2
105806f32e7eSjoerg       // homogeneous float/vector aggregate ABI, and to avoid having to use
105906f32e7eSjoerg       // "byval" when passing aggregates that might fully fit in registers.
106006f32e7eSjoerg       return Ty->isArrayTy();
106106f32e7eSjoerg     }
106206f32e7eSjoerg 
106306f32e7eSjoerg     /// If a physical register, this returns the register that receives the
106406f32e7eSjoerg     /// exception address on entry to an EH pad.
1065*da58b97aSjoerg     Register
106606f32e7eSjoerg     getExceptionPointerRegister(const Constant *PersonalityFn) const override;
106706f32e7eSjoerg 
106806f32e7eSjoerg     /// If a physical register, this returns the register that receives the
106906f32e7eSjoerg     /// exception typeid on entry to a landing pad.
1070*da58b97aSjoerg     Register
107106f32e7eSjoerg     getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
107206f32e7eSjoerg 
107306f32e7eSjoerg     /// Override to support customized stack guard loading.
107406f32e7eSjoerg     bool useLoadStackGuardNode() const override;
107506f32e7eSjoerg     void insertSSPDeclarations(Module &M) const override;
107606f32e7eSjoerg 
107706f32e7eSjoerg     bool isFPImmLegal(const APFloat &Imm, EVT VT,
107806f32e7eSjoerg                       bool ForCodeSize) const override;
107906f32e7eSjoerg 
108006f32e7eSjoerg     unsigned getJumpTableEncoding() const override;
108106f32e7eSjoerg     bool isJumpTableRelative() const override;
108206f32e7eSjoerg     SDValue getPICJumpTableRelocBase(SDValue Table,
108306f32e7eSjoerg                                      SelectionDAG &DAG) const override;
108406f32e7eSjoerg     const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
108506f32e7eSjoerg                                                unsigned JTI,
108606f32e7eSjoerg                                                MCContext &Ctx) const override;
108706f32e7eSjoerg 
1088*da58b97aSjoerg     /// SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode),
1089*da58b97aSjoerg     /// compute the address flags of the node, get the optimal address mode
1090*da58b97aSjoerg     /// based on the flags, and set the Base and Disp based on the address mode.
1091*da58b97aSjoerg     PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N,
1092*da58b97aSjoerg                                         SDValue &Disp, SDValue &Base,
1093*da58b97aSjoerg                                         SelectionDAG &DAG,
1094*da58b97aSjoerg                                         MaybeAlign Align) const;
1095*da58b97aSjoerg     /// SelectForceXFormMode - Given the specified address, force it to be
1096*da58b97aSjoerg     /// represented as an indexed [r+r] operation (an XForm instruction).
1097*da58b97aSjoerg     PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base,
1098*da58b97aSjoerg                                        SelectionDAG &DAG) const;
1099*da58b97aSjoerg 
1100*da58b97aSjoerg     /// Structure that collects some common arguments that get passed around
1101*da58b97aSjoerg     /// between the functions for call lowering.
1102*da58b97aSjoerg     struct CallFlags {
1103*da58b97aSjoerg       const CallingConv::ID CallConv;
1104*da58b97aSjoerg       const bool IsTailCall : 1;
1105*da58b97aSjoerg       const bool IsVarArg : 1;
1106*da58b97aSjoerg       const bool IsPatchPoint : 1;
1107*da58b97aSjoerg       const bool IsIndirect : 1;
1108*da58b97aSjoerg       const bool HasNest : 1;
1109*da58b97aSjoerg       const bool NoMerge : 1;
1110*da58b97aSjoerg 
CallFlagsCallFlags1111*da58b97aSjoerg       CallFlags(CallingConv::ID CC, bool IsTailCall, bool IsVarArg,
1112*da58b97aSjoerg                 bool IsPatchPoint, bool IsIndirect, bool HasNest, bool NoMerge)
1113*da58b97aSjoerg           : CallConv(CC), IsTailCall(IsTailCall), IsVarArg(IsVarArg),
1114*da58b97aSjoerg             IsPatchPoint(IsPatchPoint), IsIndirect(IsIndirect),
1115*da58b97aSjoerg             HasNest(HasNest), NoMerge(NoMerge) {}
1116*da58b97aSjoerg     };
1117*da58b97aSjoerg 
111806f32e7eSjoerg   private:
111906f32e7eSjoerg     struct ReuseLoadInfo {
112006f32e7eSjoerg       SDValue Ptr;
112106f32e7eSjoerg       SDValue Chain;
112206f32e7eSjoerg       SDValue ResChain;
112306f32e7eSjoerg       MachinePointerInfo MPI;
112406f32e7eSjoerg       bool IsDereferenceable = false;
112506f32e7eSjoerg       bool IsInvariant = false;
1126*da58b97aSjoerg       Align Alignment;
112706f32e7eSjoerg       AAMDNodes AAInfo;
112806f32e7eSjoerg       const MDNode *Ranges = nullptr;
112906f32e7eSjoerg 
113006f32e7eSjoerg       ReuseLoadInfo() = default;
113106f32e7eSjoerg 
MMOFlagsReuseLoadInfo113206f32e7eSjoerg       MachineMemOperand::Flags MMOFlags() const {
113306f32e7eSjoerg         MachineMemOperand::Flags F = MachineMemOperand::MONone;
113406f32e7eSjoerg         if (IsDereferenceable)
113506f32e7eSjoerg           F |= MachineMemOperand::MODereferenceable;
113606f32e7eSjoerg         if (IsInvariant)
113706f32e7eSjoerg           F |= MachineMemOperand::MOInvariant;
113806f32e7eSjoerg         return F;
113906f32e7eSjoerg       }
114006f32e7eSjoerg     };
114106f32e7eSjoerg 
1142*da58b97aSjoerg     // Map that relates a set of common address flags to PPC addressing modes.
1143*da58b97aSjoerg     std::map<PPC::AddrMode, SmallVector<unsigned, 16>> AddrModesMap;
1144*da58b97aSjoerg     void initializeAddrModeMap();
114506f32e7eSjoerg 
114606f32e7eSjoerg     bool canReuseLoadAddress(SDValue Op, EVT MemVT, ReuseLoadInfo &RLI,
114706f32e7eSjoerg                              SelectionDAG &DAG,
114806f32e7eSjoerg                              ISD::LoadExtType ET = ISD::NON_EXTLOAD) const;
114906f32e7eSjoerg     void spliceIntoChain(SDValue ResChain, SDValue NewResChain,
115006f32e7eSjoerg                          SelectionDAG &DAG) const;
115106f32e7eSjoerg 
115206f32e7eSjoerg     void LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
115306f32e7eSjoerg                                 SelectionDAG &DAG, const SDLoc &dl) const;
115406f32e7eSjoerg     SDValue LowerFP_TO_INTDirectMove(SDValue Op, SelectionDAG &DAG,
115506f32e7eSjoerg                                      const SDLoc &dl) const;
115606f32e7eSjoerg 
115706f32e7eSjoerg     bool directMoveIsProfitable(const SDValue &Op) const;
115806f32e7eSjoerg     SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG &DAG,
115906f32e7eSjoerg                                      const SDLoc &dl) const;
116006f32e7eSjoerg 
116106f32e7eSjoerg     SDValue LowerINT_TO_FPVector(SDValue Op, SelectionDAG &DAG,
116206f32e7eSjoerg                                  const SDLoc &dl) const;
116306f32e7eSjoerg 
116406f32e7eSjoerg     SDValue LowerTRUNCATEVector(SDValue Op, SelectionDAG &DAG) const;
116506f32e7eSjoerg 
116606f32e7eSjoerg     SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;
116706f32e7eSjoerg     SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;
116806f32e7eSjoerg 
116906f32e7eSjoerg     bool
117006f32e7eSjoerg     IsEligibleForTailCallOptimization(SDValue Callee,
117106f32e7eSjoerg                                       CallingConv::ID CalleeCC,
117206f32e7eSjoerg                                       bool isVarArg,
117306f32e7eSjoerg                                       const SmallVectorImpl<ISD::InputArg> &Ins,
117406f32e7eSjoerg                                       SelectionDAG& DAG) const;
117506f32e7eSjoerg 
1176*da58b97aSjoerg     bool IsEligibleForTailCallOptimization_64SVR4(
1177*da58b97aSjoerg         SDValue Callee, CallingConv::ID CalleeCC, const CallBase *CB,
1178*da58b97aSjoerg         bool isVarArg, const SmallVectorImpl<ISD::OutputArg> &Outs,
1179*da58b97aSjoerg         const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const;
118006f32e7eSjoerg 
118106f32e7eSjoerg     SDValue EmitTailCallLoadFPAndRetAddr(SelectionDAG &DAG, int SPDiff,
118206f32e7eSjoerg                                          SDValue Chain, SDValue &LROpOut,
118306f32e7eSjoerg                                          SDValue &FPOpOut,
118406f32e7eSjoerg                                          const SDLoc &dl) const;
118506f32e7eSjoerg 
118606f32e7eSjoerg     SDValue getTOCEntry(SelectionDAG &DAG, const SDLoc &dl, SDValue GA) const;
118706f32e7eSjoerg 
118806f32e7eSjoerg     SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
118906f32e7eSjoerg     SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
119006f32e7eSjoerg     SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
119106f32e7eSjoerg     SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
119206f32e7eSjoerg     SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
1193*da58b97aSjoerg     SDValue LowerGlobalTLSAddressAIX(SDValue Op, SelectionDAG &DAG) const;
1194*da58b97aSjoerg     SDValue LowerGlobalTLSAddressLinux(SDValue Op, SelectionDAG &DAG) const;
119506f32e7eSjoerg     SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
119606f32e7eSjoerg     SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
119706f32e7eSjoerg     SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
119806f32e7eSjoerg     SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
119906f32e7eSjoerg     SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
1200*da58b97aSjoerg     SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
120106f32e7eSjoerg     SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
120206f32e7eSjoerg     SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const;
120306f32e7eSjoerg     SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
120406f32e7eSjoerg     SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
120506f32e7eSjoerg     SDValue LowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const;
120606f32e7eSjoerg     SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
120706f32e7eSjoerg     SDValue LowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
120806f32e7eSjoerg     SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
120906f32e7eSjoerg     SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
121006f32e7eSjoerg     SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;
121106f32e7eSjoerg     SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
121206f32e7eSjoerg     SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
121306f32e7eSjoerg                            const SDLoc &dl) const;
121406f32e7eSjoerg     SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
121506f32e7eSjoerg     SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) const;
121606f32e7eSjoerg     SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const;
121706f32e7eSjoerg     SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const;
121806f32e7eSjoerg     SDValue LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) const;
1219*da58b97aSjoerg     SDValue LowerFunnelShift(SDValue Op, SelectionDAG &DAG) const;
122006f32e7eSjoerg     SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
122106f32e7eSjoerg     SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
122206f32e7eSjoerg     SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
122306f32e7eSjoerg     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
122406f32e7eSjoerg     SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
122506f32e7eSjoerg     SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const;
122606f32e7eSjoerg     SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
122706f32e7eSjoerg     SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;
122806f32e7eSjoerg     SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const;
122906f32e7eSjoerg     SDValue LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
1230*da58b97aSjoerg     SDValue LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const;
1231*da58b97aSjoerg     SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;
123206f32e7eSjoerg 
123306f32e7eSjoerg     SDValue LowerVectorLoad(SDValue Op, SelectionDAG &DAG) const;
123406f32e7eSjoerg     SDValue LowerVectorStore(SDValue Op, SelectionDAG &DAG) const;
123506f32e7eSjoerg 
123606f32e7eSjoerg     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
123706f32e7eSjoerg                             CallingConv::ID CallConv, bool isVarArg,
123806f32e7eSjoerg                             const SmallVectorImpl<ISD::InputArg> &Ins,
123906f32e7eSjoerg                             const SDLoc &dl, SelectionDAG &DAG,
124006f32e7eSjoerg                             SmallVectorImpl<SDValue> &InVals) const;
1241*da58b97aSjoerg 
1242*da58b97aSjoerg     SDValue FinishCall(CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG,
124306f32e7eSjoerg                        SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
124406f32e7eSjoerg                        SDValue InFlag, SDValue Chain, SDValue CallSeqStart,
124506f32e7eSjoerg                        SDValue &Callee, int SPDiff, unsigned NumBytes,
124606f32e7eSjoerg                        const SmallVectorImpl<ISD::InputArg> &Ins,
124706f32e7eSjoerg                        SmallVectorImpl<SDValue> &InVals,
1248*da58b97aSjoerg                        const CallBase *CB) const;
124906f32e7eSjoerg 
125006f32e7eSjoerg     SDValue
125106f32e7eSjoerg     LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
125206f32e7eSjoerg                          const SmallVectorImpl<ISD::InputArg> &Ins,
125306f32e7eSjoerg                          const SDLoc &dl, SelectionDAG &DAG,
125406f32e7eSjoerg                          SmallVectorImpl<SDValue> &InVals) const override;
125506f32e7eSjoerg 
125606f32e7eSjoerg     SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
125706f32e7eSjoerg                       SmallVectorImpl<SDValue> &InVals) const override;
125806f32e7eSjoerg 
125906f32e7eSjoerg     bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
126006f32e7eSjoerg                         bool isVarArg,
126106f32e7eSjoerg                         const SmallVectorImpl<ISD::OutputArg> &Outs,
126206f32e7eSjoerg                         LLVMContext &Context) const override;
126306f32e7eSjoerg 
126406f32e7eSjoerg     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
126506f32e7eSjoerg                         const SmallVectorImpl<ISD::OutputArg> &Outs,
126606f32e7eSjoerg                         const SmallVectorImpl<SDValue> &OutVals,
126706f32e7eSjoerg                         const SDLoc &dl, SelectionDAG &DAG) const override;
126806f32e7eSjoerg 
126906f32e7eSjoerg     SDValue extendArgForPPC64(ISD::ArgFlagsTy Flags, EVT ObjectVT,
127006f32e7eSjoerg                               SelectionDAG &DAG, SDValue ArgVal,
127106f32e7eSjoerg                               const SDLoc &dl) const;
127206f32e7eSjoerg 
1273*da58b97aSjoerg     SDValue LowerFormalArguments_AIX(
127406f32e7eSjoerg         SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
127506f32e7eSjoerg         const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
127606f32e7eSjoerg         SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
127706f32e7eSjoerg     SDValue LowerFormalArguments_64SVR4(
127806f32e7eSjoerg         SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
127906f32e7eSjoerg         const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
128006f32e7eSjoerg         SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
128106f32e7eSjoerg     SDValue LowerFormalArguments_32SVR4(
128206f32e7eSjoerg         SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
128306f32e7eSjoerg         const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
128406f32e7eSjoerg         SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const;
128506f32e7eSjoerg 
128606f32e7eSjoerg     SDValue createMemcpyOutsideCallSeq(SDValue Arg, SDValue PtrOff,
128706f32e7eSjoerg                                        SDValue CallSeqStart,
128806f32e7eSjoerg                                        ISD::ArgFlagsTy Flags, SelectionDAG &DAG,
128906f32e7eSjoerg                                        const SDLoc &dl) const;
129006f32e7eSjoerg 
1291*da58b97aSjoerg     SDValue LowerCall_64SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags,
129206f32e7eSjoerg                              const SmallVectorImpl<ISD::OutputArg> &Outs,
129306f32e7eSjoerg                              const SmallVectorImpl<SDValue> &OutVals,
129406f32e7eSjoerg                              const SmallVectorImpl<ISD::InputArg> &Ins,
129506f32e7eSjoerg                              const SDLoc &dl, SelectionDAG &DAG,
129606f32e7eSjoerg                              SmallVectorImpl<SDValue> &InVals,
1297*da58b97aSjoerg                              const CallBase *CB) const;
1298*da58b97aSjoerg     SDValue LowerCall_32SVR4(SDValue Chain, SDValue Callee, CallFlags CFlags,
129906f32e7eSjoerg                              const SmallVectorImpl<ISD::OutputArg> &Outs,
130006f32e7eSjoerg                              const SmallVectorImpl<SDValue> &OutVals,
130106f32e7eSjoerg                              const SmallVectorImpl<ISD::InputArg> &Ins,
130206f32e7eSjoerg                              const SDLoc &dl, SelectionDAG &DAG,
130306f32e7eSjoerg                              SmallVectorImpl<SDValue> &InVals,
1304*da58b97aSjoerg                              const CallBase *CB) const;
1305*da58b97aSjoerg     SDValue LowerCall_AIX(SDValue Chain, SDValue Callee, CallFlags CFlags,
130606f32e7eSjoerg                           const SmallVectorImpl<ISD::OutputArg> &Outs,
130706f32e7eSjoerg                           const SmallVectorImpl<SDValue> &OutVals,
130806f32e7eSjoerg                           const SmallVectorImpl<ISD::InputArg> &Ins,
130906f32e7eSjoerg                           const SDLoc &dl, SelectionDAG &DAG,
131006f32e7eSjoerg                           SmallVectorImpl<SDValue> &InVals,
1311*da58b97aSjoerg                           const CallBase *CB) const;
131206f32e7eSjoerg 
131306f32e7eSjoerg     SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
131406f32e7eSjoerg     SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
131506f32e7eSjoerg     SDValue LowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
131606f32e7eSjoerg 
131706f32e7eSjoerg     SDValue DAGCombineExtBoolTrunc(SDNode *N, DAGCombinerInfo &DCI) const;
131806f32e7eSjoerg     SDValue DAGCombineBuildVector(SDNode *N, DAGCombinerInfo &DCI) const;
131906f32e7eSjoerg     SDValue DAGCombineTruncBoolExt(SDNode *N, DAGCombinerInfo &DCI) const;
132006f32e7eSjoerg     SDValue combineStoreFPToInt(SDNode *N, DAGCombinerInfo &DCI) const;
132106f32e7eSjoerg     SDValue combineFPToIntToFP(SDNode *N, DAGCombinerInfo &DCI) const;
132206f32e7eSjoerg     SDValue combineSHL(SDNode *N, DAGCombinerInfo &DCI) const;
132306f32e7eSjoerg     SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const;
132406f32e7eSjoerg     SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const;
132506f32e7eSjoerg     SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;
132606f32e7eSjoerg     SDValue combineADD(SDNode *N, DAGCombinerInfo &DCI) const;
1327*da58b97aSjoerg     SDValue combineFMALike(SDNode *N, DAGCombinerInfo &DCI) const;
132806f32e7eSjoerg     SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const;
132906f32e7eSjoerg     SDValue combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const;
133006f32e7eSjoerg     SDValue combineABS(SDNode *N, DAGCombinerInfo &DCI) const;
133106f32e7eSjoerg     SDValue combineVSelect(SDNode *N, DAGCombinerInfo &DCI) const;
1332*da58b97aSjoerg     SDValue combineVectorShuffle(ShuffleVectorSDNode *SVN,
1333*da58b97aSjoerg                                  SelectionDAG &DAG) const;
133406f32e7eSjoerg     SDValue combineVReverseMemOP(ShuffleVectorSDNode *SVN, LSBaseSDNode *LSBase,
133506f32e7eSjoerg                                  DAGCombinerInfo &DCI) const;
133606f32e7eSjoerg 
133706f32e7eSjoerg     /// ConvertSETCCToSubtract - looks at SETCC that compares ints. It replaces
133806f32e7eSjoerg     /// SETCC with integer subtraction when (1) there is a legal way of doing it
133906f32e7eSjoerg     /// (2) keeping the result of comparison in GPR has performance benefit.
134006f32e7eSjoerg     SDValue ConvertSETCCToSubtract(SDNode *N, DAGCombinerInfo &DCI) const;
134106f32e7eSjoerg 
134206f32e7eSjoerg     SDValue getSqrtEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,
134306f32e7eSjoerg                             int &RefinementSteps, bool &UseOneConstNR,
134406f32e7eSjoerg                             bool Reciprocal) const override;
134506f32e7eSjoerg     SDValue getRecipEstimate(SDValue Operand, SelectionDAG &DAG, int Enabled,
134606f32e7eSjoerg                              int &RefinementSteps) const override;
1347*da58b97aSjoerg     SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG,
1348*da58b97aSjoerg                              const DenormalMode &Mode) const override;
1349*da58b97aSjoerg     SDValue getSqrtResultForDenormInput(SDValue Operand,
1350*da58b97aSjoerg                                         SelectionDAG &DAG) const override;
135106f32e7eSjoerg     unsigned combineRepeatedFPDivisors() const override;
135206f32e7eSjoerg 
135306f32e7eSjoerg     SDValue
135406f32e7eSjoerg     combineElementTruncationToVectorTruncation(SDNode *N,
135506f32e7eSjoerg                                                DAGCombinerInfo &DCI) const;
135606f32e7eSjoerg 
135706f32e7eSjoerg     /// lowerToVINSERTH - Return the SDValue if this VECTOR_SHUFFLE can be
135806f32e7eSjoerg     /// handled by the VINSERTH instruction introduced in ISA 3.0. This is
135906f32e7eSjoerg     /// essentially any shuffle of v8i16 vectors that just inserts one element
136006f32e7eSjoerg     /// from one vector into the other.
136106f32e7eSjoerg     SDValue lowerToVINSERTH(ShuffleVectorSDNode *N, SelectionDAG &DAG) const;
136206f32e7eSjoerg 
136306f32e7eSjoerg     /// lowerToVINSERTB - Return the SDValue if this VECTOR_SHUFFLE can be
136406f32e7eSjoerg     /// handled by the VINSERTB instruction introduced in ISA 3.0. This is
136506f32e7eSjoerg     /// essentially v16i8 vector version of VINSERTH.
136606f32e7eSjoerg     SDValue lowerToVINSERTB(ShuffleVectorSDNode *N, SelectionDAG &DAG) const;
136706f32e7eSjoerg 
1368*da58b97aSjoerg     /// lowerToXXSPLTI32DX - Return the SDValue if this VECTOR_SHUFFLE can be
1369*da58b97aSjoerg     /// handled by the XXSPLTI32DX instruction introduced in ISA 3.1.
1370*da58b97aSjoerg     SDValue lowerToXXSPLTI32DX(ShuffleVectorSDNode *N, SelectionDAG &DAG) const;
1371*da58b97aSjoerg 
137206f32e7eSjoerg     // Return whether the call instruction can potentially be optimized to a
137306f32e7eSjoerg     // tail call. This will cause the optimizers to attempt to move, or
137406f32e7eSjoerg     // duplicate return instructions to help enable tail call optimizations.
137506f32e7eSjoerg     bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
137606f32e7eSjoerg     bool hasBitPreservingFPLogic(EVT VT) const override;
137706f32e7eSjoerg     bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override;
1378*da58b97aSjoerg 
1379*da58b97aSjoerg     /// getAddrModeForFlags - Based on the set of address flags, select the most
1380*da58b97aSjoerg     /// optimal instruction format to match by.
1381*da58b97aSjoerg     PPC::AddrMode getAddrModeForFlags(unsigned Flags) const;
1382*da58b97aSjoerg 
1383*da58b97aSjoerg     /// computeMOFlags - Given a node N and it's Parent (a MemSDNode), compute
1384*da58b97aSjoerg     /// the address flags of the load/store instruction that is to be matched.
1385*da58b97aSjoerg     /// The address flags are stored in a map, which is then searched
1386*da58b97aSjoerg     /// through to determine the optimal load/store instruction format.
1387*da58b97aSjoerg     unsigned computeMOFlags(const SDNode *Parent, SDValue N,
1388*da58b97aSjoerg                             SelectionDAG &DAG) const;
138906f32e7eSjoerg   }; // end class PPCTargetLowering
139006f32e7eSjoerg 
139106f32e7eSjoerg   namespace PPC {
139206f32e7eSjoerg 
139306f32e7eSjoerg     FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
139406f32e7eSjoerg                              const TargetLibraryInfo *LibInfo);
139506f32e7eSjoerg 
139606f32e7eSjoerg   } // end namespace PPC
139706f32e7eSjoerg 
139806f32e7eSjoerg   bool isIntS16Immediate(SDNode *N, int16_t &Imm);
139906f32e7eSjoerg   bool isIntS16Immediate(SDValue Op, int16_t &Imm);
1400*da58b97aSjoerg   bool isIntS34Immediate(SDNode *N, int64_t &Imm);
1401*da58b97aSjoerg   bool isIntS34Immediate(SDValue Op, int64_t &Imm);
1402*da58b97aSjoerg 
1403*da58b97aSjoerg   bool convertToNonDenormSingle(APInt &ArgAPInt);
1404*da58b97aSjoerg   bool convertToNonDenormSingle(APFloat &ArgAPFloat);
1405*da58b97aSjoerg   bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat);
140606f32e7eSjoerg 
140706f32e7eSjoerg } // end namespace llvm
140806f32e7eSjoerg 
140906f32e7eSjoerg #endif // LLVM_TARGET_POWERPC_PPC32ISELLOWERING_H
1410