1//===-- SystemZISelLowering.h - SystemZ DAG lowering interface --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that SystemZ uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
15#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZISELLOWERING_H
16
17#include "SystemZ.h"
18#include "SystemZInstrInfo.h"
19#include "llvm/CodeGen/LibcallLoweringInfo.h"
20#include "llvm/CodeGen/MachineBasicBlock.h"
21#include "llvm/CodeGen/SelectionDAG.h"
22#include "llvm/CodeGen/TargetLowering.h"
23#include <optional>
24
25namespace llvm {
26
27namespace SystemZICMP {
28// Describes whether an integer comparison needs to be signed or unsigned,
29// or whether either type is OK.
30enum {
31 Any,
32 UnsignedOnly,
33 SignedOnly
34};
35} // end namespace SystemZICMP
36
37class SystemZSubtarget;
38
39class SystemZTargetLowering : public TargetLowering {
40public:
41 explicit SystemZTargetLowering(const TargetMachine &TM,
42 const SystemZSubtarget &STI);
43
44 bool useSoftFloat() const override;
45
46 // Override TargetLowering.
47 MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override {
48 return MVT::i32;
49 }
50 unsigned getVectorIdxWidth(const DataLayout &DL) const override {
51 // Only the lower 12 bits of an element index are used, so we don't
52 // want to clobber the upper 32 bits of a GPR unnecessarily.
53 return 32;
54 }
55 TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT)
56 const override {
57 // Widen subvectors to the full width rather than promoting integer
58 // elements. This is better because:
59 //
60 // (a) it means that we can handle the ABI for passing and returning
61 // sub-128 vectors without having to handle them as legal types.
62 //
63 // (b) we don't have instructions to extend on load and truncate on store,
64 // so promoting the integers is less efficient.
65 //
66 // (c) there are no multiplication instructions for the widest integer
67 // type (v2i64).
68
69 // Expand (narrow) f16 vectors during type legalization to avoid
70 // operations for all elements as with expansion after widening.
71 if (VT.getScalarType() == MVT::f16)
72 return VT.getVectorElementCount().isScalar() ? TypeScalarizeVector
73 : TypeSplitVector;
74 if (VT.getScalarSizeInBits() % 8 == 0)
75 return TypeWidenVector;
76 return TargetLoweringBase::getPreferredVectorAction(VT);
77 }
78 unsigned
79 getNumRegisters(LLVMContext &Context, EVT VT,
80 std::optional<MVT> RegisterVT) const override {
81 // i128 inline assembly operand.
82 if (VT == MVT::i128 && RegisterVT && *RegisterVT == MVT::Untyped)
83 return 1;
84 return TargetLowering::getNumRegisters(Context, VT);
85 }
86 unsigned
87 getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC,
88 EVT VT, EVT &IntermediateVT,
89 unsigned &NumIntermediates,
90 MVT &RegisterVT) const override;
91 MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC,
92 EVT VT) const override;
93 unsigned getNumRegistersForCallingConv(LLVMContext &Context,
94 CallingConv::ID CC,
95 EVT VT) const override;
96 bool isCheapToSpeculateCtlz(Type *) const override { return true; }
97 bool isCheapToSpeculateCttz(Type *) const override { return true; }
98 bool preferZeroCompareBranch() const override { return true; }
99 bool isMaskAndCmp0FoldingBeneficial(const Instruction &AndI) const override {
100 ConstantInt* Mask = dyn_cast<ConstantInt>(Val: AndI.getOperand(i: 1));
101 return Mask && Mask->getValue().isIntN(N: 16);
102 }
103 bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
104 return VT.isScalarInteger();
105 }
106 EVT getSetCCResultType(const DataLayout &DL, LLVMContext &,
107 EVT) const override;
108 bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
109 EVT VT) const override;
110 bool isFPImmLegal(const APFloat &Imm, EVT VT,
111 bool ForCodeSize) const override;
112 bool ShouldShrinkFPConstant(EVT VT) const override {
113 // Do not shrink 64-bit FP constpool entries since LDEB is slower than
114 // LD, and having the full constant in memory enables reg/mem opcodes.
115 return VT != MVT::f64;
116 }
117 MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
118 MachineBasicBlock *MBB) const;
119
120 MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
121 MachineBasicBlock *MBB) const;
122
123 bool hasInlineStackProbe(const MachineFunction &MF) const override;
124 AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override;
125 AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override;
126 AtomicExpansionKind
127 shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override;
128 bool isLegalICmpImmediate(int64_t Imm) const override;
129 bool isLegalAddImmediate(int64_t Imm) const override;
130 bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
131 unsigned AS,
132 Instruction *I = nullptr) const override;
133 bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment,
134 MachineMemOperand::Flags Flags,
135 unsigned *Fast) const override;
136 bool findOptimalMemOpLowering(LLVMContext &Context, std::vector<EVT> &MemOps,
137 unsigned Limit, const MemOp &Op, unsigned DstAS,
138 unsigned SrcAS,
139 const AttributeList &FuncAttributes,
140 EVT *LargestVT = nullptr) const override;
141 EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op,
142 const AttributeList &FuncAttributes) const override;
143 bool isTruncateFree(Type *, Type *) const override;
144 bool isTruncateFree(EVT, EVT) const override;
145
146 bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
147 bool MathUsed) const override {
148 // Form add and sub with overflow intrinsics regardless of any extra
149 // users of the math result.
150 return VT == MVT::i32 || VT == MVT::i64 || VT == MVT::i128;
151 }
152
153 bool shouldConsiderGEPOffsetSplit() const override { return true; }
154
155 bool preferSelectsOverBooleanArithmetic(EVT VT) const override {
156 return true;
157 }
158
159 bool isProfitableToCombineMinNumMaxNum(EVT VT) const override {
160 // We have instructions for pseudo min/max, no need to convert them to
161 // minnum/maxnum.
162 return false;
163 }
164
165 // This function currently returns cost for srl/ipm/cc sequence for merging.
166 CondMergingParams
167 getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs,
168 const Value *Rhs,
169 const Function *F) const override;
170
171 // Handle Lowering flag assembly outputs.
172 SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
173 const SDLoc &DL,
174 const AsmOperandInfo &Constraint,
175 SelectionDAG &DAG) const override;
176
177 std::pair<unsigned, const TargetRegisterClass *>
178 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
179 StringRef Constraint, MVT VT) const override;
180 TargetLowering::ConstraintType
181 getConstraintType(StringRef Constraint) const override;
182 TargetLowering::ConstraintWeight
183 getSingleConstraintMatchWeight(AsmOperandInfo &info,
184 const char *constraint) const override;
185 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
186 std::vector<SDValue> &Ops,
187 SelectionDAG &DAG) const override;
188
189 InlineAsm::ConstraintCode
190 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
191 if (ConstraintCode.size() == 1) {
192 switch(ConstraintCode[0]) {
193 default:
194 break;
195 case 'o':
196 return InlineAsm::ConstraintCode::o;
197 case 'Q':
198 return InlineAsm::ConstraintCode::Q;
199 case 'R':
200 return InlineAsm::ConstraintCode::R;
201 case 'S':
202 return InlineAsm::ConstraintCode::S;
203 case 'T':
204 return InlineAsm::ConstraintCode::T;
205 }
206 } else if (ConstraintCode.size() == 2 && ConstraintCode[0] == 'Z') {
207 switch (ConstraintCode[1]) {
208 default:
209 break;
210 case 'Q':
211 return InlineAsm::ConstraintCode::ZQ;
212 case 'R':
213 return InlineAsm::ConstraintCode::ZR;
214 case 'S':
215 return InlineAsm::ConstraintCode::ZS;
216 case 'T':
217 return InlineAsm::ConstraintCode::ZT;
218 }
219 }
220 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
221 }
222
223 Register getRegisterByName(const char *RegName, LLT VT,
224 const MachineFunction &MF) const override;
225
226 /// If a physical register, this returns the register that receives the
227 /// exception address on entry to an EH pad.
228 Register
229 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
230
231 /// If a physical register, this returns the register that receives the
232 /// exception typeid on entry to a landing pad.
233 Register
234 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
235
236 /// Override to support customized stack guard loading.
237 bool useLoadStackGuardNode(const Module &M) const override { return true; }
238 /// Insert SSP declaration if global stack protector is used.
239 void
240 insertSSPDeclarations(Module &M,
241 const LibcallLoweringInfo &Libcalls) const override;
242 MachineBasicBlock *
243 EmitInstrWithCustomInserter(MachineInstr &MI,
244 MachineBasicBlock *BB) const override;
245 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
246 void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
247 SelectionDAG &DAG) const override;
248 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
249 SelectionDAG &DAG) const override;
250 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
251 bool allowTruncateForTailCall(Type *, Type *) const override;
252 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
253 bool splitValueIntoRegisterParts(
254 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
255 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
256 const override;
257 SDValue joinRegisterPartsIntoValue(
258 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
259 unsigned NumParts, MVT PartVT, EVT ValueVT,
260 std::optional<CallingConv::ID> CC) const override;
261 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
262 bool isVarArg,
263 const SmallVectorImpl<ISD::InputArg> &Ins,
264 const SDLoc &DL, SelectionDAG &DAG,
265 SmallVectorImpl<SDValue> &InVals) const override;
266 SDValue LowerCall(CallLoweringInfo &CLI,
267 SmallVectorImpl<SDValue> &InVals) const override;
268
269 std::pair<SDValue, SDValue>
270 makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName,
271 EVT RetVT, ArrayRef<SDValue> Ops, CallingConv::ID CallConv,
272 bool IsSigned, SDLoc DL, bool DoesNotReturn,
273 bool IsReturnValueUsed) const;
274
275 SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg,
276 SDLoc DL, SDValue Chain, bool IsStrict) const;
277
278 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
279 bool isVarArg,
280 const SmallVectorImpl<ISD::OutputArg> &Outs,
281 LLVMContext &Context,
282 const Type *RetTy) const override;
283 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
284 const SmallVectorImpl<ISD::OutputArg> &Outs,
285 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
286 SelectionDAG &DAG) const override;
287 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
288
289 /// Determine which of the bits specified in Mask are known to be either
290 /// zero or one and return them in the KnownZero/KnownOne bitsets.
291 void computeKnownBitsForTargetNode(const SDValue Op,
292 KnownBits &Known,
293 const APInt &DemandedElts,
294 const SelectionDAG &DAG,
295 unsigned Depth = 0) const override;
296
297 /// Determine the number of bits in the operation that are sign bits.
298 unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
299 const APInt &DemandedElts,
300 const SelectionDAG &DAG,
301 unsigned Depth) const override;
302
303 bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
304 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
305 UndefPoisonKind Kind, unsigned Depth) const override;
306
307 ISD::NodeType getExtendForAtomicOps() const override {
308 return ISD::ANY_EXTEND;
309 }
310 ISD::NodeType getExtendForAtomicCmpSwapArg() const override {
311 return ISD::ZERO_EXTEND;
312 }
313
314 bool supportSwiftError() const override {
315 return true;
316 }
317
318 unsigned getStackProbeSize(const MachineFunction &MF) const;
319 bool hasAndNot(SDValue Y) const override;
320
321private:
322 const SystemZSubtarget &Subtarget;
323
324 // Implement LowerOperation for individual opcodes.
325 SDValue getVectorCmp(SelectionDAG &DAG, unsigned Opcode,
326 const SDLoc &DL, EVT VT,
327 SDValue CmpOp0, SDValue CmpOp1, SDValue Chain) const;
328 SDValue lowerVectorSETCC(SelectionDAG &DAG, const SDLoc &DL,
329 EVT VT, ISD::CondCode CC,
330 SDValue CmpOp0, SDValue CmpOp1,
331 SDValue Chain = SDValue(),
332 bool IsSignaling = false) const;
333 SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
334 SDValue lowerSTRICT_FSETCC(SDValue Op, SelectionDAG &DAG,
335 bool IsSignaling) const;
336 SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
337 SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
338 SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
339 SelectionDAG &DAG) const;
340 SDValue lowerTLSGetOffset(GlobalAddressSDNode *Node,
341 SelectionDAG &DAG, unsigned Opcode,
342 SDValue GOTOffset) const;
343 SDValue lowerThreadPointer(const SDLoc &DL, SelectionDAG &DAG) const;
344 SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
345 SelectionDAG &DAG) const;
346 SDValue lowerBlockAddress(BlockAddressSDNode *Node,
347 SelectionDAG &DAG) const;
348 SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
349 SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
350 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
351 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
352 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
353 SDValue lowerVASTART_ELF(SDValue Op, SelectionDAG &DAG) const;
354 SDValue lowerVASTART_XPLINK(SDValue Op, SelectionDAG &DAG) const;
355 SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
356 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
357 SDValue lowerDYNAMIC_STACKALLOC_ELF(SDValue Op, SelectionDAG &DAG) const;
358 SDValue lowerDYNAMIC_STACKALLOC_XPLINK(SDValue Op, SelectionDAG &DAG) const;
359 SDValue lowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const;
360 SDValue lowerMULH(SDValue Op, SelectionDAG &DAG, unsigned Opcode) const;
361 SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
362 SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
363 SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
364 SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
365 SDValue lowerXALUO(SDValue Op, SelectionDAG &DAG) const;
366 SDValue lowerUADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;
367 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
368 SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
369 SDValue lowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
370 SDValue lowerVECREDUCE_ADD(SDValue Op, SelectionDAG &DAG) const;
371 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
372 SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
373 SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
374 SDValue lowerATOMIC_LDST_I128(SDValue Op, SelectionDAG &DAG) const;
375 SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
376 unsigned Opcode) const;
377 SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
378 SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
379 SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
380 SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
381 SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
382 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
383 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
384 bool isVectorElementLoad(SDValue Op) const;
385 SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
386 SmallVectorImpl<SDValue> &Elems) const;
387 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
388 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
389 SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;
390 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
391 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
392 SDValue lowerSIGN_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
393 SDValue lowerZERO_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
394 SDValue lowerShift(SDValue Op, SelectionDAG &DAG, unsigned ByScalar) const;
395 SDValue lowerFSHL(SDValue Op, SelectionDAG &DAG) const;
396 SDValue lowerFSHR(SDValue Op, SelectionDAG &DAG) const;
397 SDValue lowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
398 SDValue lower_FP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
399 SDValue lower_INT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
400 SDValue lowerLoadF16(SDValue Op, SelectionDAG &DAG) const;
401 SDValue lowerStoreF16(SDValue Op, SelectionDAG &DAG) const;
402
403 SDValue lowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
404 SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
405 SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
406
407 bool canTreatAsByteVector(EVT VT) const;
408 SDValue combineExtract(const SDLoc &DL, EVT ElemVT, EVT VecVT, SDValue OrigOp,
409 unsigned Index, DAGCombinerInfo &DCI,
410 bool Force) const;
411 SDValue combineTruncateExtract(const SDLoc &DL, EVT TruncVT, SDValue Op,
412 DAGCombinerInfo &DCI) const;
413 SDValue combineZERO_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
414 SDValue combineSIGN_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
415 SDValue combineSIGN_EXTEND_INREG(SDNode *N, DAGCombinerInfo &DCI) const;
416 SDValue combineMERGE(SDNode *N, DAGCombinerInfo &DCI) const;
417 bool canLoadStoreByteSwapped(EVT VT) const;
418 SDValue combineLOAD(SDNode *N, DAGCombinerInfo &DCI) const;
419 SDValue combineSTORE(SDNode *N, DAGCombinerInfo &DCI) const;
420 SDValue combineVECTOR_SHUFFLE(SDNode *N, DAGCombinerInfo &DCI) const;
421 SDValue combineEXTRACT_VECTOR_ELT(SDNode *N, DAGCombinerInfo &DCI) const;
422 SDValue combineJOIN_DWORDS(SDNode *N, DAGCombinerInfo &DCI) const;
423 SDValue combineFP_ROUND(SDNode *N, DAGCombinerInfo &DCI) const;
424 SDValue combineFP_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
425 SDValue combineINT_TO_FP(SDNode *N, DAGCombinerInfo &DCI) const;
426 SDValue combineFCOPYSIGN(SDNode *N, DAGCombinerInfo &DCI) const;
427 SDValue combineBSWAP(SDNode *N, DAGCombinerInfo &DCI) const;
428 SDValue combineSETCC(SDNode *N, DAGCombinerInfo &DCI) const;
429 SDValue combineBR_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
430 SDValue combineSELECT_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
431 SDValue combineGET_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
432 SDValue combineShiftToMulAddHigh(SDNode *N, DAGCombinerInfo &DCI) const;
433 SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;
434 SDValue combineIntDIVREM(SDNode *N, DAGCombinerInfo &DCI) const;
435 SDValue combineINTRINSIC(SDNode *N, DAGCombinerInfo &DCI) const;
436
437 SDValue unwrapAddress(SDValue N) const override;
438
439 // If the last instruction before MBBI in MBB was some form of COMPARE,
440 // try to replace it with a COMPARE AND BRANCH just before MBBI.
441 // CCMask and Target are the BRC-like operands for the branch.
442 // Return true if the change was made.
443 bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
444 MachineBasicBlock::iterator MBBI,
445 unsigned CCMask,
446 MachineBasicBlock *Target) const;
447
448 // Implement EmitInstrWithCustomInserter for individual operation types.
449 MachineBasicBlock *emitAdjCallStack(MachineInstr &MI,
450 MachineBasicBlock *BB) const;
451 MachineBasicBlock *emitSelect(MachineInstr &MI, MachineBasicBlock *BB) const;
452 MachineBasicBlock *emitCondStore(MachineInstr &MI, MachineBasicBlock *BB,
453 unsigned StoreOpcode, unsigned STOCOpcode,
454 bool Invert) const;
455 MachineBasicBlock *emitICmp128Hi(MachineInstr &MI, MachineBasicBlock *BB,
456 bool Unsigned) const;
457 MachineBasicBlock *emitPair128(MachineInstr &MI,
458 MachineBasicBlock *MBB) const;
459 MachineBasicBlock *emitExt128(MachineInstr &MI, MachineBasicBlock *MBB,
460 bool ClearEven) const;
461 MachineBasicBlock *emitAtomicLoadBinary(MachineInstr &MI,
462 MachineBasicBlock *BB,
463 unsigned BinOpcode,
464 bool Invert = false) const;
465 MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr &MI,
466 MachineBasicBlock *MBB,
467 unsigned CompareOpcode,
468 unsigned KeepOldMask) const;
469 MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr &MI,
470 MachineBasicBlock *BB) const;
471 MachineBasicBlock *emitMemMemWrapper(MachineInstr &MI, MachineBasicBlock *BB,
472 unsigned Opcode,
473 bool IsMemset = false) const;
474 MachineBasicBlock *emitStringWrapper(MachineInstr &MI, MachineBasicBlock *BB,
475 unsigned Opcode) const;
476 MachineBasicBlock *emitTransactionBegin(MachineInstr &MI,
477 MachineBasicBlock *MBB,
478 unsigned Opcode, bool NoFloat) const;
479 MachineBasicBlock *emitLoadAndTestCmp0(MachineInstr &MI,
480 MachineBasicBlock *MBB,
481 unsigned Opcode) const;
482 MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,
483 MachineBasicBlock *MBB) const;
484 MachineBasicBlock *emitStackGuardPseudo(MachineInstr &MI,
485 MachineBasicBlock *MBB,
486 unsigned PseudoOp) const;
487 SDValue getBackchainAddress(SDValue SP, SelectionDAG &DAG) const;
488
489 MachineMemOperand::Flags
490 getTargetMMOFlags(const Instruction &I) const override;
491 const TargetRegisterClass *getRepRegClassFor(MVT VT) const override;
492
493private:
494 bool isInternal(const Function *Fn) const;
495 mutable std::map<const Function *, bool> IsInternalCache;
496 void verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
497 const Function *F, SDValue Callee) const;
498 void verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
499 const Function *F) const;
500 bool
501 verifyNarrowIntegerArgs(const SmallVectorImpl<ISD::OutputArg> &Outs) const;
502
503public:
504};
505
506struct SystemZVectorConstantInfo {
507private:
508 APInt IntBits; // The 128 bits as an integer.
509 APInt SplatBits; // Smallest splat value.
510 APInt SplatUndef; // Bits correspoding to undef operands of the BVN.
511 unsigned SplatBitSize = 0;
512 bool isFP128 = false;
513public:
514 unsigned Opcode = 0;
515 SmallVector<unsigned, 2> OpVals;
516 MVT VecVT;
517 SystemZVectorConstantInfo(APInt IntImm);
518 SystemZVectorConstantInfo(APFloat FPImm)
519 : SystemZVectorConstantInfo(FPImm.bitcastToAPInt()) {
520 isFP128 = (&FPImm.getSemantics() == &APFloat::IEEEquad());
521 }
522 SystemZVectorConstantInfo(BuildVectorSDNode *BVN);
523 bool isVectorConstantLegal(const SystemZSubtarget &Subtarget);
524};
525
526} // end namespace llvm
527
528#endif
529