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