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 // This function currently returns cost for srl/ipm/cc sequence for merging.
160 CondMergingParams
161 getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs,
162 const Value *Rhs) const override;
163
164 // Handle Lowering flag assembly outputs.
165 SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag,
166 const SDLoc &DL,
167 const AsmOperandInfo &Constraint,
168 SelectionDAG &DAG) const override;
169
170 std::pair<unsigned, const TargetRegisterClass *>
171 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
172 StringRef Constraint, MVT VT) const override;
173 TargetLowering::ConstraintType
174 getConstraintType(StringRef Constraint) const override;
175 TargetLowering::ConstraintWeight
176 getSingleConstraintMatchWeight(AsmOperandInfo &info,
177 const char *constraint) const override;
178 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint,
179 std::vector<SDValue> &Ops,
180 SelectionDAG &DAG) const override;
181
182 InlineAsm::ConstraintCode
183 getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
184 if (ConstraintCode.size() == 1) {
185 switch(ConstraintCode[0]) {
186 default:
187 break;
188 case 'o':
189 return InlineAsm::ConstraintCode::o;
190 case 'Q':
191 return InlineAsm::ConstraintCode::Q;
192 case 'R':
193 return InlineAsm::ConstraintCode::R;
194 case 'S':
195 return InlineAsm::ConstraintCode::S;
196 case 'T':
197 return InlineAsm::ConstraintCode::T;
198 }
199 } else if (ConstraintCode.size() == 2 && ConstraintCode[0] == 'Z') {
200 switch (ConstraintCode[1]) {
201 default:
202 break;
203 case 'Q':
204 return InlineAsm::ConstraintCode::ZQ;
205 case 'R':
206 return InlineAsm::ConstraintCode::ZR;
207 case 'S':
208 return InlineAsm::ConstraintCode::ZS;
209 case 'T':
210 return InlineAsm::ConstraintCode::ZT;
211 }
212 }
213 return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
214 }
215
216 Register getRegisterByName(const char *RegName, LLT VT,
217 const MachineFunction &MF) const override;
218
219 /// If a physical register, this returns the register that receives the
220 /// exception address on entry to an EH pad.
221 Register
222 getExceptionPointerRegister(const Constant *PersonalityFn) const override;
223
224 /// If a physical register, this returns the register that receives the
225 /// exception typeid on entry to a landing pad.
226 Register
227 getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
228
229 /// Override to support customized stack guard loading.
230 bool useLoadStackGuardNode(const Module &M) const override { return true; }
231 /// Insert SSP declaration if global stack protector is used.
232 void
233 insertSSPDeclarations(Module &M,
234 const LibcallLoweringInfo &Libcalls) const override;
235 MachineBasicBlock *
236 EmitInstrWithCustomInserter(MachineInstr &MI,
237 MachineBasicBlock *BB) const override;
238 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
239 void LowerOperationWrapper(SDNode *N, SmallVectorImpl<SDValue> &Results,
240 SelectionDAG &DAG) const override;
241 void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
242 SelectionDAG &DAG) const override;
243 const MCPhysReg *getScratchRegisters(CallingConv::ID CC) const override;
244 bool allowTruncateForTailCall(Type *, Type *) const override;
245 bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
246 bool splitValueIntoRegisterParts(
247 SelectionDAG & DAG, const SDLoc &DL, SDValue Val, SDValue *Parts,
248 unsigned NumParts, MVT PartVT, std::optional<CallingConv::ID> CC)
249 const override;
250 SDValue joinRegisterPartsIntoValue(
251 SelectionDAG & DAG, const SDLoc &DL, const SDValue *Parts,
252 unsigned NumParts, MVT PartVT, EVT ValueVT,
253 std::optional<CallingConv::ID> CC) const override;
254 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
255 bool isVarArg,
256 const SmallVectorImpl<ISD::InputArg> &Ins,
257 const SDLoc &DL, SelectionDAG &DAG,
258 SmallVectorImpl<SDValue> &InVals) const override;
259 SDValue LowerCall(CallLoweringInfo &CLI,
260 SmallVectorImpl<SDValue> &InVals) const override;
261
262 std::pair<SDValue, SDValue>
263 makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName,
264 EVT RetVT, ArrayRef<SDValue> Ops, CallingConv::ID CallConv,
265 bool IsSigned, SDLoc DL, bool DoesNotReturn,
266 bool IsReturnValueUsed) const;
267
268 SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg,
269 SDLoc DL, SDValue Chain, bool IsStrict) const;
270
271 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
272 bool isVarArg,
273 const SmallVectorImpl<ISD::OutputArg> &Outs,
274 LLVMContext &Context,
275 const Type *RetTy) const override;
276 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
277 const SmallVectorImpl<ISD::OutputArg> &Outs,
278 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
279 SelectionDAG &DAG) const override;
280 SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
281
282 /// Determine which of the bits specified in Mask are known to be either
283 /// zero or one and return them in the KnownZero/KnownOne bitsets.
284 void computeKnownBitsForTargetNode(const SDValue Op,
285 KnownBits &Known,
286 const APInt &DemandedElts,
287 const SelectionDAG &DAG,
288 unsigned Depth = 0) const override;
289
290 /// Determine the number of bits in the operation that are sign bits.
291 unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
292 const APInt &DemandedElts,
293 const SelectionDAG &DAG,
294 unsigned Depth) const override;
295
296 bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(
297 SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG,
298 UndefPoisonKind Kind, unsigned Depth) const override;
299
300 ISD::NodeType getExtendForAtomicOps() const override {
301 return ISD::ANY_EXTEND;
302 }
303 ISD::NodeType getExtendForAtomicCmpSwapArg() const override {
304 return ISD::ZERO_EXTEND;
305 }
306
307 bool supportSwiftError() const override {
308 return true;
309 }
310
311 unsigned getStackProbeSize(const MachineFunction &MF) const;
312 bool hasAndNot(SDValue Y) const override;
313
314private:
315 const SystemZSubtarget &Subtarget;
316
317 // Implement LowerOperation for individual opcodes.
318 SDValue getVectorCmp(SelectionDAG &DAG, unsigned Opcode,
319 const SDLoc &DL, EVT VT,
320 SDValue CmpOp0, SDValue CmpOp1, SDValue Chain) const;
321 SDValue lowerVectorSETCC(SelectionDAG &DAG, const SDLoc &DL,
322 EVT VT, ISD::CondCode CC,
323 SDValue CmpOp0, SDValue CmpOp1,
324 SDValue Chain = SDValue(),
325 bool IsSignaling = false) const;
326 SDValue lowerSETCC(SDValue Op, SelectionDAG &DAG) const;
327 SDValue lowerSTRICT_FSETCC(SDValue Op, SelectionDAG &DAG,
328 bool IsSignaling) const;
329 SDValue lowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
330 SDValue lowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
331 SDValue lowerGlobalAddress(GlobalAddressSDNode *Node,
332 SelectionDAG &DAG) const;
333 SDValue lowerTLSGetOffset(GlobalAddressSDNode *Node,
334 SelectionDAG &DAG, unsigned Opcode,
335 SDValue GOTOffset) const;
336 SDValue lowerThreadPointer(const SDLoc &DL, SelectionDAG &DAG) const;
337 SDValue lowerGlobalTLSAddress(GlobalAddressSDNode *Node,
338 SelectionDAG &DAG) const;
339 SDValue lowerBlockAddress(BlockAddressSDNode *Node,
340 SelectionDAG &DAG) const;
341 SDValue lowerJumpTable(JumpTableSDNode *JT, SelectionDAG &DAG) const;
342 SDValue lowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
343 SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
344 SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
345 SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
346 SDValue lowerVASTART_ELF(SDValue Op, SelectionDAG &DAG) const;
347 SDValue lowerVASTART_XPLINK(SDValue Op, SelectionDAG &DAG) const;
348 SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
349 SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
350 SDValue lowerDYNAMIC_STACKALLOC_ELF(SDValue Op, SelectionDAG &DAG) const;
351 SDValue lowerDYNAMIC_STACKALLOC_XPLINK(SDValue Op, SelectionDAG &DAG) const;
352 SDValue lowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const;
353 SDValue lowerMULH(SDValue Op, SelectionDAG &DAG, unsigned Opcode) const;
354 SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
355 SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
356 SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
357 SDValue lowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
358 SDValue lowerXALUO(SDValue Op, SelectionDAG &DAG) const;
359 SDValue lowerUADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;
360 SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
361 SDValue lowerOR(SDValue Op, SelectionDAG &DAG) const;
362 SDValue lowerCTPOP(SDValue Op, SelectionDAG &DAG) const;
363 SDValue lowerVECREDUCE_ADD(SDValue Op, SelectionDAG &DAG) const;
364 SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
365 SDValue lowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
366 SDValue lowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
367 SDValue lowerATOMIC_LDST_I128(SDValue Op, SelectionDAG &DAG) const;
368 SDValue lowerATOMIC_LOAD_OP(SDValue Op, SelectionDAG &DAG,
369 unsigned Opcode) const;
370 SDValue lowerATOMIC_LOAD_SUB(SDValue Op, SelectionDAG &DAG) const;
371 SDValue lowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
372 SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
373 SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
374 SDValue lowerPREFETCH(SDValue Op, SelectionDAG &DAG) const;
375 SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
376 SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
377 bool isVectorElementLoad(SDValue Op) const;
378 SDValue buildVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT,
379 SmallVectorImpl<SDValue> &Elems) const;
380 SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
381 SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
382 SDValue lowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG) const;
383 SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
384 SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const;
385 SDValue lowerSIGN_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
386 SDValue lowerZERO_EXTEND_VECTOR_INREG(SDValue Op, SelectionDAG &DAG) const;
387 SDValue lowerShift(SDValue Op, SelectionDAG &DAG, unsigned ByScalar) const;
388 SDValue lowerFSHL(SDValue Op, SelectionDAG &DAG) const;
389 SDValue lowerFSHR(SDValue Op, SelectionDAG &DAG) const;
390 SDValue lowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const;
391 SDValue lower_FP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
392 SDValue lower_INT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
393 SDValue lowerLoadF16(SDValue Op, SelectionDAG &DAG) const;
394 SDValue lowerStoreF16(SDValue Op, SelectionDAG &DAG) const;
395
396 SDValue lowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
397 SDValue lowerGET_ROUNDING(SDValue Op, SelectionDAG &DAG) const;
398 SDValue lowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const;
399
400 bool canTreatAsByteVector(EVT VT) const;
401 SDValue combineExtract(const SDLoc &DL, EVT ElemVT, EVT VecVT, SDValue OrigOp,
402 unsigned Index, DAGCombinerInfo &DCI,
403 bool Force) const;
404 SDValue combineTruncateExtract(const SDLoc &DL, EVT TruncVT, SDValue Op,
405 DAGCombinerInfo &DCI) const;
406 SDValue combineZERO_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
407 SDValue combineSIGN_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
408 SDValue combineSIGN_EXTEND_INREG(SDNode *N, DAGCombinerInfo &DCI) const;
409 SDValue combineMERGE(SDNode *N, DAGCombinerInfo &DCI) const;
410 bool canLoadStoreByteSwapped(EVT VT) const;
411 SDValue combineLOAD(SDNode *N, DAGCombinerInfo &DCI) const;
412 SDValue combineSTORE(SDNode *N, DAGCombinerInfo &DCI) const;
413 SDValue combineVECTOR_SHUFFLE(SDNode *N, DAGCombinerInfo &DCI) const;
414 SDValue combineEXTRACT_VECTOR_ELT(SDNode *N, DAGCombinerInfo &DCI) const;
415 SDValue combineJOIN_DWORDS(SDNode *N, DAGCombinerInfo &DCI) const;
416 SDValue combineFP_ROUND(SDNode *N, DAGCombinerInfo &DCI) const;
417 SDValue combineFP_EXTEND(SDNode *N, DAGCombinerInfo &DCI) const;
418 SDValue combineINT_TO_FP(SDNode *N, DAGCombinerInfo &DCI) const;
419 SDValue combineFCOPYSIGN(SDNode *N, DAGCombinerInfo &DCI) const;
420 SDValue combineBSWAP(SDNode *N, DAGCombinerInfo &DCI) const;
421 SDValue combineSETCC(SDNode *N, DAGCombinerInfo &DCI) const;
422 SDValue combineBR_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
423 SDValue combineSELECT_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
424 SDValue combineGET_CCMASK(SDNode *N, DAGCombinerInfo &DCI) const;
425 SDValue combineShiftToMulAddHigh(SDNode *N, DAGCombinerInfo &DCI) const;
426 SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;
427 SDValue combineIntDIVREM(SDNode *N, DAGCombinerInfo &DCI) const;
428 SDValue combineINTRINSIC(SDNode *N, DAGCombinerInfo &DCI) const;
429
430 SDValue unwrapAddress(SDValue N) const override;
431
432 // If the last instruction before MBBI in MBB was some form of COMPARE,
433 // try to replace it with a COMPARE AND BRANCH just before MBBI.
434 // CCMask and Target are the BRC-like operands for the branch.
435 // Return true if the change was made.
436 bool convertPrevCompareToBranch(MachineBasicBlock *MBB,
437 MachineBasicBlock::iterator MBBI,
438 unsigned CCMask,
439 MachineBasicBlock *Target) const;
440
441 // Implement EmitInstrWithCustomInserter for individual operation types.
442 MachineBasicBlock *emitAdjCallStack(MachineInstr &MI,
443 MachineBasicBlock *BB) const;
444 MachineBasicBlock *emitSelect(MachineInstr &MI, MachineBasicBlock *BB) const;
445 MachineBasicBlock *emitCondStore(MachineInstr &MI, MachineBasicBlock *BB,
446 unsigned StoreOpcode, unsigned STOCOpcode,
447 bool Invert) const;
448 MachineBasicBlock *emitICmp128Hi(MachineInstr &MI, MachineBasicBlock *BB,
449 bool Unsigned) const;
450 MachineBasicBlock *emitPair128(MachineInstr &MI,
451 MachineBasicBlock *MBB) const;
452 MachineBasicBlock *emitExt128(MachineInstr &MI, MachineBasicBlock *MBB,
453 bool ClearEven) const;
454 MachineBasicBlock *emitAtomicLoadBinary(MachineInstr &MI,
455 MachineBasicBlock *BB,
456 unsigned BinOpcode,
457 bool Invert = false) const;
458 MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr &MI,
459 MachineBasicBlock *MBB,
460 unsigned CompareOpcode,
461 unsigned KeepOldMask) const;
462 MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr &MI,
463 MachineBasicBlock *BB) const;
464 MachineBasicBlock *emitMemMemWrapper(MachineInstr &MI, MachineBasicBlock *BB,
465 unsigned Opcode,
466 bool IsMemset = false) const;
467 MachineBasicBlock *emitStringWrapper(MachineInstr &MI, MachineBasicBlock *BB,
468 unsigned Opcode) const;
469 MachineBasicBlock *emitTransactionBegin(MachineInstr &MI,
470 MachineBasicBlock *MBB,
471 unsigned Opcode, bool NoFloat) const;
472 MachineBasicBlock *emitLoadAndTestCmp0(MachineInstr &MI,
473 MachineBasicBlock *MBB,
474 unsigned Opcode) const;
475 MachineBasicBlock *emitProbedAlloca(MachineInstr &MI,
476 MachineBasicBlock *MBB) const;
477 MachineBasicBlock *emitStackGuardPseudo(MachineInstr &MI,
478 MachineBasicBlock *MBB,
479 unsigned PseudoOp) const;
480 SDValue getBackchainAddress(SDValue SP, SelectionDAG &DAG) const;
481
482 MachineMemOperand::Flags
483 getTargetMMOFlags(const Instruction &I) const override;
484 const TargetRegisterClass *getRepRegClassFor(MVT VT) const override;
485
486private:
487 bool isInternal(const Function *Fn) const;
488 mutable std::map<const Function *, bool> IsInternalCache;
489 void verifyNarrowIntegerArgs_Call(const SmallVectorImpl<ISD::OutputArg> &Outs,
490 const Function *F, SDValue Callee) const;
491 void verifyNarrowIntegerArgs_Ret(const SmallVectorImpl<ISD::OutputArg> &Outs,
492 const Function *F) const;
493 bool
494 verifyNarrowIntegerArgs(const SmallVectorImpl<ISD::OutputArg> &Outs) const;
495
496public:
497};
498
499struct SystemZVectorConstantInfo {
500private:
501 APInt IntBits; // The 128 bits as an integer.
502 APInt SplatBits; // Smallest splat value.
503 APInt SplatUndef; // Bits correspoding to undef operands of the BVN.
504 unsigned SplatBitSize = 0;
505 bool isFP128 = false;
506public:
507 unsigned Opcode = 0;
508 SmallVector<unsigned, 2> OpVals;
509 MVT VecVT;
510 SystemZVectorConstantInfo(APInt IntImm);
511 SystemZVectorConstantInfo(APFloat FPImm)
512 : SystemZVectorConstantInfo(FPImm.bitcastToAPInt()) {
513 isFP128 = (&FPImm.getSemantics() == &APFloat::IEEEquad());
514 }
515 SystemZVectorConstantInfo(BuildVectorSDNode *BVN);
516 bool isVectorConstantLegal(const SystemZSubtarget &Subtarget);
517};
518
519} // end namespace llvm
520
521#endif
522