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