1//===-- SystemZInstrInfo.cpp - SystemZ instruction information ------------===//
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 contains the SystemZ implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SystemZInstrInfo.h"
14#include "MCTargetDesc/SystemZMCTargetDesc.h"
15#include "SystemZ.h"
16#include "SystemZInstrBuilder.h"
17#include "SystemZSubtarget.h"
18#include "llvm/ADT/Statistic.h"
19#include "llvm/CodeGen/LiveInterval.h"
20#include "llvm/CodeGen/LiveIntervals.h"
21#include "llvm/CodeGen/LiveRegUnits.h"
22#include "llvm/CodeGen/MachineBasicBlock.h"
23#include "llvm/CodeGen/MachineFrameInfo.h"
24#include "llvm/CodeGen/MachineFunction.h"
25#include "llvm/CodeGen/MachineInstr.h"
26#include "llvm/CodeGen/MachineMemOperand.h"
27#include "llvm/CodeGen/MachineOperand.h"
28#include "llvm/CodeGen/MachineRegisterInfo.h"
29#include "llvm/CodeGen/SlotIndexes.h"
30#include "llvm/CodeGen/StackMaps.h"
31#include "llvm/CodeGen/TargetInstrInfo.h"
32#include "llvm/CodeGen/TargetOpcodes.h"
33#include "llvm/CodeGen/TargetSubtargetInfo.h"
34#include "llvm/CodeGen/VirtRegMap.h"
35#include "llvm/IR/Module.h"
36#include "llvm/MC/MCInstBuilder.h"
37#include "llvm/MC/MCInstrDesc.h"
38#include "llvm/MC/MCRegisterInfo.h"
39#include "llvm/Support/BranchProbability.h"
40#include "llvm/Support/ErrorHandling.h"
41#include "llvm/Support/MathExtras.h"
42#include "llvm/Target/TargetMachine.h"
43#include <cassert>
44#include <cstdint>
45#include <iterator>
46
47using namespace llvm;
48
49#define GET_INSTRINFO_CTOR_DTOR
50#define GET_INSTRMAP_INFO
51#include "SystemZGenInstrInfo.inc"
52
53#define DEBUG_TYPE "systemz-II"
54
55// Return a mask with Count low bits set.
56static uint64_t allOnes(unsigned int Count) {
57 return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1;
58}
59
60// Pin the vtable to this file.
61void SystemZInstrInfo::anchor() {}
62
63SystemZInstrInfo::SystemZInstrInfo(const SystemZSubtarget &sti)
64 : SystemZGenInstrInfo(sti, RI, -1, -1),
65 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister(),
66 sti.getHwMode()),
67 STI(sti) {}
68
69// MI is a 128-bit load or store. Split it into two 64-bit loads or stores,
70// each having the opcode given by NewOpcode.
71void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI,
72 unsigned NewOpcode) const {
73 MachineBasicBlock *MBB = MI->getParent();
74 MachineFunction &MF = *MBB->getParent();
75
76 // Get two load or store instructions. Use the original instruction for
77 // one of them and create a clone for the other.
78 MachineInstr *HighPartMI = MF.CloneMachineInstr(Orig: &*MI);
79 MachineInstr *LowPartMI = &*MI;
80 MBB->insert(I: LowPartMI, MI: HighPartMI);
81
82 // Set up the two 64-bit registers and remember super reg and its flags.
83 MachineOperand &HighRegOp = HighPartMI->getOperand(i: 0);
84 MachineOperand &LowRegOp = LowPartMI->getOperand(i: 0);
85 Register Reg128 = LowRegOp.getReg();
86 RegState Reg128Killed = getKillRegState(B: LowRegOp.isKill());
87 RegState Reg128Undef = getUndefRegState(B: LowRegOp.isUndef());
88 HighRegOp.setReg(RI.getSubReg(Reg: HighRegOp.getReg(), Idx: SystemZ::subreg_h64));
89 LowRegOp.setReg(RI.getSubReg(Reg: LowRegOp.getReg(), Idx: SystemZ::subreg_l64));
90
91 // The address in the first (high) instruction is already correct.
92 // Adjust the offset in the second (low) instruction.
93 MachineOperand &HighOffsetOp = HighPartMI->getOperand(i: 2);
94 MachineOperand &LowOffsetOp = LowPartMI->getOperand(i: 2);
95 LowOffsetOp.setImm(LowOffsetOp.getImm() + 8);
96
97 // Set the opcodes.
98 unsigned HighOpcode = getOpcodeForOffset(Opcode: NewOpcode, Offset: HighOffsetOp.getImm());
99 unsigned LowOpcode = getOpcodeForOffset(Opcode: NewOpcode, Offset: LowOffsetOp.getImm());
100 assert(HighOpcode && LowOpcode && "Both offsets should be in range");
101 HighPartMI->setDesc(get(Opcode: HighOpcode));
102 LowPartMI->setDesc(get(Opcode: LowOpcode));
103
104 MachineInstr *FirstMI = HighPartMI;
105 if (MI->mayStore()) {
106 FirstMI->getOperand(i: 0).setIsKill(false);
107 // Add implicit uses of the super register in case one of the subregs is
108 // undefined. We could track liveness and skip storing an undefined
109 // subreg, but this is hopefully rare (discovered with llvm-stress).
110 // If Reg128 was killed, set kill flag on MI.
111 RegState Reg128UndefImpl = (Reg128Undef | RegState::Implicit);
112 MachineInstrBuilder(MF, HighPartMI).addReg(RegNo: Reg128, Flags: Reg128UndefImpl);
113 MachineInstrBuilder(MF, LowPartMI).addReg(RegNo: Reg128, Flags: (Reg128UndefImpl | Reg128Killed));
114 } else {
115 // If HighPartMI clobbers any of the address registers, it needs to come
116 // after LowPartMI.
117 auto overlapsAddressReg = [&](Register Reg) -> bool {
118 return RI.regsOverlap(RegA: Reg, RegB: MI->getOperand(i: 1).getReg()) ||
119 RI.regsOverlap(RegA: Reg, RegB: MI->getOperand(i: 3).getReg());
120 };
121 if (overlapsAddressReg(HighRegOp.getReg())) {
122 assert(!overlapsAddressReg(LowRegOp.getReg()) &&
123 "Both loads clobber address!");
124 MBB->splice(Where: HighPartMI, Other: MBB, From: LowPartMI);
125 FirstMI = LowPartMI;
126 }
127 }
128
129 // Clear the kill flags on the address registers in the first instruction.
130 FirstMI->getOperand(i: 1).setIsKill(false);
131 FirstMI->getOperand(i: 3).setIsKill(false);
132}
133
134// Split ADJDYNALLOC instruction MI.
135void SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const {
136 MachineBasicBlock *MBB = MI->getParent();
137 MachineFunction &MF = *MBB->getParent();
138 MachineFrameInfo &MFFrame = MF.getFrameInfo();
139 MachineOperand &OffsetMO = MI->getOperand(i: 2);
140 SystemZCallingConventionRegisters *Regs = STI.getSpecialRegisters();
141
142 uint64_t Offset = (MFFrame.getMaxCallFrameSize() +
143 Regs->getCallFrameSize() +
144 Regs->getStackPointerBias() +
145 OffsetMO.getImm());
146 unsigned NewOpcode = getOpcodeForOffset(Opcode: SystemZ::LA, Offset);
147 assert(NewOpcode && "No support for huge argument lists yet");
148 MI->setDesc(get(Opcode: NewOpcode));
149 OffsetMO.setImm(Offset);
150}
151
152// MI is an RI-style pseudo instruction. Replace it with LowOpcode
153// if the first operand is a low GR32 and HighOpcode if the first operand
154// is a high GR32. ConvertHigh is true if LowOpcode takes a signed operand
155// and HighOpcode takes an unsigned 32-bit operand. In those cases,
156// MI has the same kind of operand as LowOpcode, so needs to be converted
157// if HighOpcode is used.
158void SystemZInstrInfo::expandRIPseudo(MachineInstr &MI, unsigned LowOpcode,
159 unsigned HighOpcode,
160 bool ConvertHigh) const {
161 Register Reg = MI.getOperand(i: 0).getReg();
162 bool IsHigh = SystemZ::isHighReg(Reg);
163 MI.setDesc(get(Opcode: IsHigh ? HighOpcode : LowOpcode));
164 if (IsHigh && ConvertHigh)
165 MI.getOperand(i: 1).setImm(uint32_t(MI.getOperand(i: 1).getImm()));
166}
167
168// MI is a three-operand RIE-style pseudo instruction. Replace it with
169// LowOpcodeK if the registers are both low GR32s, otherwise use a move
170// followed by HighOpcode or LowOpcode, depending on whether the target
171// is a high or low GR32.
172void SystemZInstrInfo::expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
173 unsigned LowOpcodeK,
174 unsigned HighOpcode) const {
175 Register DestReg = MI.getOperand(i: 0).getReg();
176 Register SrcReg = MI.getOperand(i: 1).getReg();
177 bool DestIsHigh = SystemZ::isHighReg(Reg: DestReg);
178 bool SrcIsHigh = SystemZ::isHighReg(Reg: SrcReg);
179 if (!DestIsHigh && !SrcIsHigh)
180 MI.setDesc(get(Opcode: LowOpcodeK));
181 else {
182 if (DestReg != SrcReg) {
183 emitGRX32Move(MBB&: *MI.getParent(), MBBI: MI, DL: MI.getDebugLoc(), DestReg, SrcReg,
184 LowLowOpcode: SystemZ::LR, Size: 32, KillSrc: MI.getOperand(i: 1).isKill(),
185 UndefSrc: MI.getOperand(i: 1).isUndef());
186 MI.getOperand(i: 1).setReg(DestReg);
187 }
188 MI.setDesc(get(Opcode: DestIsHigh ? HighOpcode : LowOpcode));
189 MI.tieOperands(DefIdx: 0, UseIdx: 1);
190 }
191}
192
193// MI is an RXY-style pseudo instruction. Replace it with LowOpcode
194// if the first operand is a low GR32 and HighOpcode if the first operand
195// is a high GR32.
196void SystemZInstrInfo::expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode,
197 unsigned HighOpcode) const {
198 Register Reg = MI.getOperand(i: 0).getReg();
199 unsigned Opcode = getOpcodeForOffset(
200 Opcode: SystemZ::isHighReg(Reg) ? HighOpcode : LowOpcode,
201 Offset: MI.getOperand(i: 2).getImm());
202 MI.setDesc(get(Opcode));
203}
204
205// MI is a load-on-condition pseudo instruction with a single register
206// (source or destination) operand. Replace it with LowOpcode if the
207// register is a low GR32 and HighOpcode if the register is a high GR32.
208void SystemZInstrInfo::expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode,
209 unsigned HighOpcode) const {
210 Register Reg = MI.getOperand(i: 0).getReg();
211 unsigned Opcode = SystemZ::isHighReg(Reg) ? HighOpcode : LowOpcode;
212 MI.setDesc(get(Opcode));
213}
214
215// MI is an RR-style pseudo instruction that zero-extends the low Size bits
216// of one GRX32 into another. Replace it with LowOpcode if both operands
217// are low registers, otherwise use RISB[LH]G.
218void SystemZInstrInfo::expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
219 unsigned Size) const {
220 MachineInstrBuilder MIB =
221 emitGRX32Move(MBB&: *MI.getParent(), MBBI: MI, DL: MI.getDebugLoc(),
222 DestReg: MI.getOperand(i: 0).getReg(), SrcReg: MI.getOperand(i: 1).getReg(), LowLowOpcode: LowOpcode,
223 Size, KillSrc: MI.getOperand(i: 1).isKill(), UndefSrc: MI.getOperand(i: 1).isUndef());
224
225 // Keep the remaining operands as-is.
226 for (const MachineOperand &MO : llvm::drop_begin(RangeOrContainer: MI.operands(), N: 2))
227 MIB.add(MO);
228
229 MI.eraseFromParent();
230}
231
232// Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR
233// DestReg before MBBI in MBB. Use LowLowOpcode when both DestReg and SrcReg
234// are low registers, otherwise use RISB[LH]G. Size is the number of bits
235// taken from the low end of SrcReg (8 for LLCR, 16 for LLHR and 32 for LR).
236// KillSrc is true if this move is the last use of SrcReg.
237MachineInstrBuilder
238SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB,
239 MachineBasicBlock::iterator MBBI,
240 const DebugLoc &DL, unsigned DestReg,
241 unsigned SrcReg, unsigned LowLowOpcode,
242 unsigned Size, bool KillSrc,
243 bool UndefSrc) const {
244 unsigned Opcode;
245 bool DestIsHigh = SystemZ::isHighReg(Reg: DestReg);
246 bool SrcIsHigh = SystemZ::isHighReg(Reg: SrcReg);
247 if (DestIsHigh && SrcIsHigh)
248 Opcode = SystemZ::RISBHH;
249 else if (DestIsHigh && !SrcIsHigh)
250 Opcode = SystemZ::RISBHL;
251 else if (!DestIsHigh && SrcIsHigh)
252 Opcode = SystemZ::RISBLH;
253 else {
254 return BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: LowLowOpcode), DestReg)
255 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc) | getUndefRegState(B: UndefSrc));
256 }
257 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
258 return BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode), DestReg)
259 .addReg(RegNo: DestReg, Flags: RegState::Undef)
260 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc) | getUndefRegState(B: UndefSrc))
261 .addImm(Val: 32 - Size).addImm(Val: 128 + 31).addImm(Val: Rotate);
262}
263
264MachineInstr *SystemZInstrInfo::commuteInstructionImpl(MachineInstr &MI,
265 bool NewMI,
266 unsigned OpIdx1,
267 unsigned OpIdx2) const {
268 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
269 if (NewMI)
270 return *MI.getParent()->getParent()->CloneMachineInstr(Orig: &MI);
271 return MI;
272 };
273
274 switch (MI.getOpcode()) {
275 case SystemZ::SELRMux:
276 case SystemZ::SELFHR:
277 case SystemZ::SELR:
278 case SystemZ::SELGR:
279 case SystemZ::LOCRMux:
280 case SystemZ::LOCFHR:
281 case SystemZ::LOCR:
282 case SystemZ::LOCGR: {
283 auto &WorkingMI = cloneIfNew(MI);
284 // Invert condition.
285 unsigned CCValid = WorkingMI.getOperand(i: 3).getImm();
286 unsigned CCMask = WorkingMI.getOperand(i: 4).getImm();
287 WorkingMI.getOperand(i: 4).setImm(CCMask ^ CCValid);
288 return TargetInstrInfo::commuteInstructionImpl(MI&: WorkingMI, /*NewMI=*/false,
289 OpIdx1, OpIdx2);
290 }
291 default:
292 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
293 }
294}
295
296// If MI is a simple load or store for a frame object, return the register
297// it loads or stores and set FrameIndex to the index of the frame object.
298// Return 0 otherwise.
299//
300// Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores.
301static int isSimpleMove(const MachineInstr &MI, int &FrameIndex,
302 unsigned Flag) {
303 const MCInstrDesc &MCID = MI.getDesc();
304 if ((MCID.TSFlags & Flag) && MI.getOperand(i: 1).isFI() &&
305 MI.getOperand(i: 2).getImm() == 0 && MI.getOperand(i: 3).getReg() == 0) {
306 FrameIndex = MI.getOperand(i: 1).getIndex();
307 return MI.getOperand(i: 0).getReg();
308 }
309 return 0;
310}
311
312Register SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
313 int &FrameIndex) const {
314 return isSimpleMove(MI, FrameIndex, Flag: SystemZII::SimpleBDXLoad);
315}
316
317Register SystemZInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
318 int &FrameIndex) const {
319 return isSimpleMove(MI, FrameIndex, Flag: SystemZII::SimpleBDXStore);
320}
321
322Register SystemZInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,
323 int &FrameIndex) const {
324 // if this is not a simple load from memory, it's not a load from stack slot
325 // either.
326 const MCInstrDesc &MCID = MI.getDesc();
327 if (!(MCID.TSFlags & SystemZII::SimpleBDXLoad))
328 return 0;
329
330 // This version of isLoadFromStackSlot should only be used post frame-index
331 // elimination.
332 assert(!MI.getOperand(1).isFI());
333
334 // Now attempt to derive frame index from MachineMemOperands.
335 SmallVector<const MachineMemOperand *, 1> Accesses;
336 if (hasLoadFromStackSlot(MI, Accesses)) {
337 FrameIndex =
338 cast<FixedStackPseudoSourceValue>(Val: Accesses.front()->getPseudoValue())
339 ->getFrameIndex();
340 return MI.getOperand(i: 0).getReg();
341 }
342 return 0;
343}
344
345Register SystemZInstrInfo::isStoreToStackSlotPostFE(const MachineInstr &MI,
346 int &FrameIndex) const {
347 // if this is not a simple store to memory, it's not a store to stack slot
348 // either.
349 const MCInstrDesc &MCID = MI.getDesc();
350 if (!(MCID.TSFlags & SystemZII::SimpleBDXStore))
351 return 0;
352
353 // This version of isStoreToStackSlot should only be used post frame-index
354 // elimination.
355 assert(!MI.getOperand(1).isFI());
356
357 // Now attempt to derive frame index from MachineMemOperands.
358 SmallVector<const MachineMemOperand *, 1> Accesses;
359 if (hasStoreToStackSlot(MI, Accesses)) {
360 FrameIndex =
361 cast<FixedStackPseudoSourceValue>(Val: Accesses.front()->getPseudoValue())
362 ->getFrameIndex();
363 return MI.getOperand(i: 0).getReg();
364 }
365 return 0;
366}
367
368bool SystemZInstrInfo::isStackSlotCopy(const MachineInstr &MI,
369 int &DestFrameIndex,
370 int &SrcFrameIndex) const {
371 // Check for MVC 0(Length,FI1),0(FI2)
372 const MachineFrameInfo &MFI = MI.getParent()->getParent()->getFrameInfo();
373 if (MI.getOpcode() != SystemZ::MVC || !MI.getOperand(i: 0).isFI() ||
374 MI.getOperand(i: 1).getImm() != 0 || !MI.getOperand(i: 3).isFI() ||
375 MI.getOperand(i: 4).getImm() != 0)
376 return false;
377
378 // Check that Length covers the full slots.
379 int64_t Length = MI.getOperand(i: 2).getImm();
380 unsigned FI1 = MI.getOperand(i: 0).getIndex();
381 unsigned FI2 = MI.getOperand(i: 3).getIndex();
382 if (MFI.getObjectSize(ObjectIdx: FI1) != Length ||
383 MFI.getObjectSize(ObjectIdx: FI2) != Length)
384 return false;
385
386 DestFrameIndex = FI1;
387 SrcFrameIndex = FI2;
388 return true;
389}
390
391bool SystemZInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
392 MachineBasicBlock *&TBB,
393 MachineBasicBlock *&FBB,
394 SmallVectorImpl<MachineOperand> &Cond,
395 bool AllowModify) const {
396 // Most of the code and comments here are boilerplate.
397
398 // Start from the bottom of the block and work up, examining the
399 // terminator instructions.
400 MachineBasicBlock::iterator I = MBB.end();
401 while (I != MBB.begin()) {
402 --I;
403 if (I->isDebugInstr())
404 continue;
405
406 // Working from the bottom, when we see a non-terminator instruction, we're
407 // done.
408 if (!isUnpredicatedTerminator(MI: *I))
409 break;
410
411 // A terminator that isn't a branch can't easily be handled by this
412 // analysis.
413 if (!I->isBranch())
414 return true;
415
416 // Can't handle indirect branches.
417 SystemZII::Branch Branch(getBranchInfo(MI: *I));
418 if (!Branch.hasMBBTarget())
419 return true;
420
421 // Punt on compound branches.
422 if (Branch.Type != SystemZII::BranchNormal)
423 return true;
424
425 if (Branch.CCMask == SystemZ::CCMASK_ANY) {
426 // Handle unconditional branches.
427 if (!AllowModify) {
428 TBB = Branch.getMBBTarget();
429 continue;
430 }
431
432 // If the block has any instructions after a JMP, delete them.
433 MBB.erase(I: std::next(x: I), E: MBB.end());
434
435 Cond.clear();
436 FBB = nullptr;
437
438 // Delete the JMP if it's equivalent to a fall-through.
439 if (MBB.isLayoutSuccessor(MBB: Branch.getMBBTarget())) {
440 TBB = nullptr;
441 I->eraseFromParent();
442 I = MBB.end();
443 continue;
444 }
445
446 // TBB is used to indicate the unconditinal destination.
447 TBB = Branch.getMBBTarget();
448 continue;
449 }
450
451 // Working from the bottom, handle the first conditional branch.
452 if (Cond.empty()) {
453 // FIXME: add X86-style branch swap
454 FBB = TBB;
455 TBB = Branch.getMBBTarget();
456 Cond.push_back(Elt: MachineOperand::CreateImm(Val: Branch.CCValid));
457 Cond.push_back(Elt: MachineOperand::CreateImm(Val: Branch.CCMask));
458 continue;
459 }
460
461 // Handle subsequent conditional branches.
462 assert(Cond.size() == 2 && TBB && "Should have seen a conditional branch");
463
464 // Only handle the case where all conditional branches branch to the same
465 // destination.
466 if (TBB != Branch.getMBBTarget())
467 return true;
468
469 // If the conditions are the same, we can leave them alone.
470 unsigned OldCCValid = Cond[0].getImm();
471 unsigned OldCCMask = Cond[1].getImm();
472 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
473 continue;
474
475 // FIXME: Try combining conditions like X86 does. Should be easy on Z!
476 return false;
477 }
478
479 return false;
480}
481
482unsigned SystemZInstrInfo::removeBranch(MachineBasicBlock &MBB,
483 int *BytesRemoved) const {
484 assert(!BytesRemoved && "code size not handled");
485
486 // Most of the code and comments here are boilerplate.
487 MachineBasicBlock::iterator I = MBB.end();
488 unsigned Count = 0;
489
490 while (I != MBB.begin()) {
491 --I;
492 if (I->isDebugInstr())
493 continue;
494 if (!I->isBranch())
495 break;
496 if (!getBranchInfo(MI: *I).hasMBBTarget())
497 break;
498 // Remove the branch.
499 I->eraseFromParent();
500 I = MBB.end();
501 ++Count;
502 }
503
504 return Count;
505}
506
507bool SystemZInstrInfo::
508reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
509 assert(Cond.size() == 2 && "Invalid condition");
510 Cond[1].setImm(Cond[1].getImm() ^ Cond[0].getImm());
511 return false;
512}
513
514unsigned SystemZInstrInfo::insertBranch(MachineBasicBlock &MBB,
515 MachineBasicBlock *TBB,
516 MachineBasicBlock *FBB,
517 ArrayRef<MachineOperand> Cond,
518 const DebugLoc &DL,
519 int *BytesAdded) const {
520 // In this function we output 32-bit branches, which should always
521 // have enough range. They can be shortened and relaxed by later code
522 // in the pipeline, if desired.
523
524 // Shouldn't be a fall through.
525 assert(TBB && "insertBranch must not be told to insert a fallthrough");
526 assert((Cond.size() == 2 || Cond.size() == 0) &&
527 "SystemZ branch conditions have one component!");
528 assert(!BytesAdded && "code size not handled");
529
530 if (Cond.empty()) {
531 // Unconditional branch?
532 assert(!FBB && "Unconditional branch with multiple successors!");
533 BuildMI(BB: &MBB, MIMD: DL, MCID: get(Opcode: SystemZ::J)).addMBB(MBB: TBB);
534 return 1;
535 }
536
537 // Conditional branch.
538 unsigned Count = 0;
539 unsigned CCValid = Cond[0].getImm();
540 unsigned CCMask = Cond[1].getImm();
541 BuildMI(BB: &MBB, MIMD: DL, MCID: get(Opcode: SystemZ::BRC))
542 .addImm(Val: CCValid).addImm(Val: CCMask).addMBB(MBB: TBB);
543 ++Count;
544
545 if (FBB) {
546 // Two-way Conditional branch. Insert the second branch.
547 BuildMI(BB: &MBB, MIMD: DL, MCID: get(Opcode: SystemZ::J)).addMBB(MBB: FBB);
548 ++Count;
549 }
550 return Count;
551}
552
553bool SystemZInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
554 Register &SrcReg2, int64_t &Mask,
555 int64_t &Value) const {
556 assert(MI.isCompare() && "Caller should have checked for a comparison");
557
558 if (MI.getNumExplicitOperands() == 2 && MI.getOperand(i: 0).isReg() &&
559 MI.getOperand(i: 1).isImm()) {
560 SrcReg = MI.getOperand(i: 0).getReg();
561 SrcReg2 = 0;
562 Value = MI.getOperand(i: 1).getImm();
563 Mask = ~0;
564 return true;
565 }
566
567 return false;
568}
569
570bool SystemZInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
571 ArrayRef<MachineOperand> Pred,
572 Register DstReg, Register TrueReg,
573 Register FalseReg, int &CondCycles,
574 int &TrueCycles,
575 int &FalseCycles) const {
576 // Not all subtargets have LOCR instructions.
577 if (!STI.hasLoadStoreOnCond())
578 return false;
579 if (Pred.size() != 2)
580 return false;
581
582 // Check register classes.
583 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
584 const TargetRegisterClass *RC =
585 RI.getCommonSubClass(A: MRI.getRegClass(Reg: TrueReg), B: MRI.getRegClass(Reg: FalseReg));
586 if (!RC)
587 return false;
588
589 // We have LOCR instructions for 32 and 64 bit general purpose registers.
590 if ((STI.hasLoadStoreOnCond2() &&
591 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
592 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
593 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
594 CondCycles = 2;
595 TrueCycles = 2;
596 FalseCycles = 2;
597 return true;
598 }
599
600 // Can't do anything else.
601 return false;
602}
603
604void SystemZInstrInfo::insertSelect(MachineBasicBlock &MBB,
605 MachineBasicBlock::iterator I,
606 const DebugLoc &DL, Register DstReg,
607 ArrayRef<MachineOperand> Pred,
608 Register TrueReg,
609 Register FalseReg) const {
610 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
611 const TargetRegisterClass *RC = MRI.getRegClass(Reg: DstReg);
612
613 assert(Pred.size() == 2 && "Invalid condition");
614 unsigned CCValid = Pred[0].getImm();
615 unsigned CCMask = Pred[1].getImm();
616
617 unsigned Opc;
618 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
619 if (STI.hasMiscellaneousExtensions3())
620 Opc = SystemZ::SELRMux;
621 else if (STI.hasLoadStoreOnCond2())
622 Opc = SystemZ::LOCRMux;
623 else {
624 Opc = SystemZ::LOCR;
625 MRI.constrainRegClass(Reg: DstReg, RC: &SystemZ::GR32BitRegClass);
626 Register TReg = MRI.createVirtualRegister(RegClass: &SystemZ::GR32BitRegClass);
627 Register FReg = MRI.createVirtualRegister(RegClass: &SystemZ::GR32BitRegClass);
628 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: TargetOpcode::COPY), DestReg: TReg).addReg(RegNo: TrueReg);
629 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: TargetOpcode::COPY), DestReg: FReg).addReg(RegNo: FalseReg);
630 TrueReg = TReg;
631 FalseReg = FReg;
632 }
633 } else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
634 if (STI.hasMiscellaneousExtensions3())
635 Opc = SystemZ::SELGR;
636 else
637 Opc = SystemZ::LOCGR;
638 } else
639 llvm_unreachable("Invalid register class");
640
641 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: Opc), DestReg: DstReg)
642 .addReg(RegNo: FalseReg).addReg(RegNo: TrueReg)
643 .addImm(Val: CCValid).addImm(Val: CCMask);
644}
645
646bool SystemZInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
647 Register Reg,
648 MachineRegisterInfo *MRI) const {
649 unsigned DefOpc = DefMI.getOpcode();
650
651 if (DefOpc == SystemZ::VGBM) {
652 int64_t ImmVal = DefMI.getOperand(i: 1).getImm();
653 if (ImmVal != 0) // TODO: Handle other values
654 return false;
655
656 // Fold gr128 = COPY (vr128 VGBM imm)
657 //
658 // %tmp:gr64 = LGHI 0
659 // to gr128 = REG_SEQUENCE %tmp, %tmp
660 assert(DefMI.getOperand(0).getReg() == Reg);
661
662 if (!UseMI.isCopy())
663 return false;
664
665 Register CopyDstReg = UseMI.getOperand(i: 0).getReg();
666 if (CopyDstReg.isVirtual() &&
667 MRI->getRegClass(Reg: CopyDstReg) == &SystemZ::GR128BitRegClass &&
668 MRI->hasOneNonDBGUse(RegNo: Reg)) {
669 // TODO: Handle physical registers
670 // TODO: Handle gr64 uses with subregister indexes
671 // TODO: Should this multi-use cases?
672 Register TmpReg = MRI->createVirtualRegister(RegClass: &SystemZ::GR64BitRegClass);
673 MachineBasicBlock &MBB = *UseMI.getParent();
674
675 loadImmediate(MBB, MBBI: UseMI.getIterator(), Reg: TmpReg, Value: ImmVal);
676
677 UseMI.setDesc(get(Opcode: SystemZ::REG_SEQUENCE));
678 UseMI.getOperand(i: 1).setReg(TmpReg);
679 MachineInstrBuilder(*MBB.getParent(), &UseMI)
680 .addImm(Val: SystemZ::subreg_h64)
681 .addReg(RegNo: TmpReg)
682 .addImm(Val: SystemZ::subreg_l64);
683
684 if (MRI->use_nodbg_empty(RegNo: Reg))
685 DefMI.eraseFromParent();
686 return true;
687 }
688
689 return false;
690 }
691
692 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
693 DefOpc != SystemZ::LGHI)
694 return false;
695 if (DefMI.getOperand(i: 0).getReg() != Reg)
696 return false;
697 int32_t ImmVal = (int32_t)DefMI.getOperand(i: 1).getImm();
698
699 unsigned UseOpc = UseMI.getOpcode();
700 unsigned NewUseOpc;
701 unsigned UseIdx;
702 int CommuteIdx = -1;
703 bool TieOps = false;
704 switch (UseOpc) {
705 case SystemZ::SELRMux:
706 TieOps = true;
707 [[fallthrough]];
708 case SystemZ::LOCRMux:
709 if (!STI.hasLoadStoreOnCond2())
710 return false;
711 NewUseOpc = SystemZ::LOCHIMux;
712 if (UseMI.getOperand(i: 2).getReg() == Reg)
713 UseIdx = 2;
714 else if (UseMI.getOperand(i: 1).getReg() == Reg)
715 UseIdx = 2, CommuteIdx = 1;
716 else
717 return false;
718 break;
719 case SystemZ::SELGR:
720 TieOps = true;
721 [[fallthrough]];
722 case SystemZ::LOCGR:
723 if (!STI.hasLoadStoreOnCond2())
724 return false;
725 NewUseOpc = SystemZ::LOCGHI;
726 if (UseMI.getOperand(i: 2).getReg() == Reg)
727 UseIdx = 2;
728 else if (UseMI.getOperand(i: 1).getReg() == Reg)
729 UseIdx = 2, CommuteIdx = 1;
730 else
731 return false;
732 break;
733 default:
734 return false;
735 }
736
737 if (CommuteIdx != -1)
738 if (!commuteInstruction(MI&: UseMI, NewMI: false, OpIdx1: CommuteIdx, OpIdx2: UseIdx))
739 return false;
740
741 bool DeleteDef = MRI->hasOneNonDBGUse(RegNo: Reg);
742 UseMI.setDesc(get(Opcode: NewUseOpc));
743 if (TieOps)
744 UseMI.tieOperands(DefIdx: 0, UseIdx: 1);
745 UseMI.getOperand(i: UseIdx).ChangeToImmediate(ImmVal);
746 if (DeleteDef)
747 DefMI.eraseFromParent();
748
749 return true;
750}
751
752bool SystemZInstrInfo::isPredicable(const MachineInstr &MI) const {
753 unsigned Opcode = MI.getOpcode();
754 if (Opcode == SystemZ::Return ||
755 Opcode == SystemZ::Return_XPLINK ||
756 Opcode == SystemZ::Trap ||
757 Opcode == SystemZ::CallJG ||
758 Opcode == SystemZ::CallBR)
759 return true;
760 return false;
761}
762
763bool SystemZInstrInfo::
764isProfitableToIfCvt(MachineBasicBlock &MBB,
765 unsigned NumCycles, unsigned ExtraPredCycles,
766 BranchProbability Probability) const {
767 // Avoid using conditional returns at the end of a loop (since then
768 // we'd need to emit an unconditional branch to the beginning anyway,
769 // making the loop body longer). This doesn't apply for low-probability
770 // loops (eg. compare-and-swap retry), so just decide based on branch
771 // probability instead of looping structure.
772 // However, since Compare and Trap instructions cost the same as a regular
773 // Compare instruction, we should allow the if conversion to convert this
774 // into a Conditional Compare regardless of the branch probability.
775 if (MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap &&
776 MBB.succ_empty() && Probability < BranchProbability(1, 8))
777 return false;
778 // For now only convert single instructions.
779 return NumCycles == 1;
780}
781
782bool SystemZInstrInfo::
783isProfitableToIfCvt(MachineBasicBlock &TMBB,
784 unsigned NumCyclesT, unsigned ExtraPredCyclesT,
785 MachineBasicBlock &FMBB,
786 unsigned NumCyclesF, unsigned ExtraPredCyclesF,
787 BranchProbability Probability) const {
788 // For now avoid converting mutually-exclusive cases.
789 return false;
790}
791
792bool SystemZInstrInfo::
793isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
794 BranchProbability Probability) const {
795 // For now only duplicate single instructions.
796 return NumCycles == 1;
797}
798
799bool SystemZInstrInfo::PredicateInstruction(
800 MachineInstr &MI, ArrayRef<MachineOperand> Pred) const {
801 assert(Pred.size() == 2 && "Invalid condition");
802 unsigned CCValid = Pred[0].getImm();
803 unsigned CCMask = Pred[1].getImm();
804 assert(CCMask > 0 && CCMask < 15 && "Invalid predicate");
805 unsigned Opcode = MI.getOpcode();
806 if (Opcode == SystemZ::Trap) {
807 MI.setDesc(get(Opcode: SystemZ::CondTrap));
808 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
809 .addImm(Val: CCValid).addImm(Val: CCMask)
810 .addReg(RegNo: SystemZ::CC, Flags: RegState::Implicit);
811 return true;
812 }
813 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
814 MI.setDesc(get(Opcode: Opcode == SystemZ::Return ? SystemZ::CondReturn
815 : SystemZ::CondReturn_XPLINK));
816 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
817 .addImm(Val: CCValid)
818 .addImm(Val: CCMask)
819 .addReg(RegNo: SystemZ::CC, Flags: RegState::Implicit);
820 return true;
821 }
822 if (Opcode == SystemZ::CallJG) {
823 MachineOperand FirstOp = MI.getOperand(i: 0);
824 const uint32_t *RegMask = MI.getOperand(i: 1).getRegMask();
825 MI.removeOperand(OpNo: 1);
826 MI.removeOperand(OpNo: 0);
827 MI.setDesc(get(Opcode: SystemZ::CallBRCL));
828 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
829 .addImm(Val: CCValid)
830 .addImm(Val: CCMask)
831 .add(MO: FirstOp)
832 .addRegMask(Mask: RegMask)
833 .addReg(RegNo: SystemZ::CC, Flags: RegState::Implicit);
834 return true;
835 }
836 if (Opcode == SystemZ::CallBR) {
837 MachineOperand Target = MI.getOperand(i: 0);
838 const uint32_t *RegMask = MI.getOperand(i: 1).getRegMask();
839 MI.removeOperand(OpNo: 1);
840 MI.removeOperand(OpNo: 0);
841 MI.setDesc(get(Opcode: SystemZ::CallBCR));
842 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
843 .addImm(Val: CCValid).addImm(Val: CCMask)
844 .add(MO: Target)
845 .addRegMask(Mask: RegMask)
846 .addReg(RegNo: SystemZ::CC, Flags: RegState::Implicit);
847 return true;
848 }
849 return false;
850}
851
852void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
853 MachineBasicBlock::iterator MBBI,
854 const DebugLoc &DL, Register DestReg,
855 Register SrcReg, bool KillSrc,
856 bool RenamableDest,
857 bool RenamableSrc) const {
858 // Split 128-bit GPR moves into two 64-bit moves. Add implicit uses of the
859 // super register in case one of the subregs is undefined.
860 // This handles ADDR128 too.
861 if (SystemZ::GR128BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg)) {
862 copyPhysReg(MBB, MBBI, DL, DestReg: RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_h64),
863 SrcReg: RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_h64), KillSrc);
864 MachineInstrBuilder(*MBB.getParent(), std::prev(x: MBBI))
865 .addReg(RegNo: SrcReg, Flags: RegState::Implicit);
866 copyPhysReg(MBB, MBBI, DL, DestReg: RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_l64),
867 SrcReg: RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_l64), KillSrc);
868 MachineInstrBuilder(*MBB.getParent(), std::prev(x: MBBI))
869 .addReg(RegNo: SrcReg, Flags: (getKillRegState(B: KillSrc) | RegState::Implicit));
870 return;
871 }
872
873 if (SystemZ::GRX32BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg)) {
874 emitGRX32Move(MBB, MBBI, DL, DestReg, SrcReg, LowLowOpcode: SystemZ::LR, Size: 32, KillSrc,
875 UndefSrc: false);
876 return;
877 }
878
879 // Move 128-bit floating-point values between VR128 and FP128.
880 if (SystemZ::VR128BitRegClass.contains(Reg: DestReg) &&
881 SystemZ::FP128BitRegClass.contains(Reg: SrcReg)) {
882 MCRegister SrcRegHi =
883 RI.getMatchingSuperReg(Reg: RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_h64),
884 SubIdx: SystemZ::subreg_h64, RC: &SystemZ::VR128BitRegClass);
885 MCRegister SrcRegLo =
886 RI.getMatchingSuperReg(Reg: RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_l64),
887 SubIdx: SystemZ::subreg_h64, RC: &SystemZ::VR128BitRegClass);
888
889 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::VMRHG), DestReg)
890 .addReg(RegNo: SrcRegHi, Flags: getKillRegState(B: KillSrc))
891 .addReg(RegNo: SrcRegLo, Flags: getKillRegState(B: KillSrc));
892 return;
893 }
894 if (SystemZ::FP128BitRegClass.contains(Reg: DestReg) &&
895 SystemZ::VR128BitRegClass.contains(Reg: SrcReg)) {
896 MCRegister DestRegHi =
897 RI.getMatchingSuperReg(Reg: RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_h64),
898 SubIdx: SystemZ::subreg_h64, RC: &SystemZ::VR128BitRegClass);
899 MCRegister DestRegLo =
900 RI.getMatchingSuperReg(Reg: RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_l64),
901 SubIdx: SystemZ::subreg_h64, RC: &SystemZ::VR128BitRegClass);
902
903 if (DestRegHi != SrcReg.asMCReg())
904 copyPhysReg(MBB, MBBI, DL, DestReg: DestRegHi, SrcReg, KillSrc: false);
905 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::VREPG), DestReg: DestRegLo)
906 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc)).addImm(Val: 1);
907 return;
908 }
909
910 if (SystemZ::FP128BitRegClass.contains(Reg: DestReg) &&
911 SystemZ::GR128BitRegClass.contains(Reg: SrcReg)) {
912 MCRegister DestRegHi = RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_h64);
913 MCRegister DestRegLo = RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_l64);
914 MCRegister SrcRegHi = RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_h64);
915 MCRegister SrcRegLo = RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_l64);
916
917 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::LDGR), DestReg: DestRegHi)
918 .addReg(RegNo: SrcRegHi)
919 .addReg(RegNo: DestReg, Flags: RegState::ImplicitDefine);
920
921 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::LDGR), DestReg: DestRegLo)
922 .addReg(RegNo: SrcRegLo, Flags: getKillRegState(B: KillSrc));
923 return;
924 }
925
926 // Move CC value from a GR32.
927 if (DestReg == SystemZ::CC) {
928 unsigned Opcode =
929 SystemZ::GR32BitRegClass.contains(Reg: SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
930 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode))
931 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc))
932 .addImm(Val: 3 << (SystemZ::IPM_CC - 16));
933 return;
934 }
935
936 if (SystemZ::GR128BitRegClass.contains(Reg: DestReg) &&
937 SystemZ::VR128BitRegClass.contains(Reg: SrcReg)) {
938 MCRegister DestH64 = RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_h64);
939 MCRegister DestL64 = RI.getSubReg(Reg: DestReg, Idx: SystemZ::subreg_l64);
940
941 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::VLGVG), DestReg: DestH64)
942 .addReg(RegNo: SrcReg)
943 .addReg(RegNo: SystemZ::NoRegister)
944 .addImm(Val: 0)
945 .addDef(RegNo: DestReg, Flags: RegState::Implicit);
946 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::VLGVG), DestReg: DestL64)
947 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc))
948 .addReg(RegNo: SystemZ::NoRegister)
949 .addImm(Val: 1);
950 return;
951 }
952
953 if (SystemZ::VR128BitRegClass.contains(Reg: DestReg) &&
954 SystemZ::GR128BitRegClass.contains(Reg: SrcReg)) {
955 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::VLVGP), DestReg)
956 .addReg(RegNo: RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_h64))
957 .addReg(RegNo: RI.getSubReg(Reg: SrcReg, Idx: SystemZ::subreg_l64));
958 return;
959 }
960
961 // Everything else needs only one instruction.
962 unsigned Opcode;
963 if (SystemZ::GR64BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
964 Opcode = SystemZ::LGR;
965 else if (SystemZ::FP16BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
966 Opcode = STI.hasVector() ? SystemZ::LDR16 : SystemZ::LER16;
967 else if (SystemZ::FP32BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
968 // For z13 we prefer LDR over LER to avoid partial register dependencies.
969 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
970 else if (SystemZ::FP64BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
971 Opcode = SystemZ::LDR;
972 else if (SystemZ::FP128BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
973 Opcode = SystemZ::LXR;
974 else if (SystemZ::VR16BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
975 Opcode = SystemZ::VLR16;
976 else if (SystemZ::VR32BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
977 Opcode = SystemZ::VLR32;
978 else if (SystemZ::VR64BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
979 Opcode = SystemZ::VLR64;
980 else if (SystemZ::VR128BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
981 Opcode = SystemZ::VLR;
982 else if (SystemZ::AR32BitRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
983 Opcode = SystemZ::CPYA;
984 else if (SystemZ::GR64BitRegClass.contains(Reg: DestReg) &&
985 SystemZ::FP64BitRegClass.contains(Reg: SrcReg))
986 Opcode = SystemZ::LGDR;
987 else if (SystemZ::FP64BitRegClass.contains(Reg: DestReg) &&
988 SystemZ::GR64BitRegClass.contains(Reg: SrcReg))
989 Opcode = SystemZ::LDGR;
990 else
991 llvm_unreachable("Impossible reg-to-reg copy");
992
993 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode), DestReg)
994 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc));
995}
996
997void SystemZInstrInfo::storeRegToStackSlot(
998 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,
999 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
1000
1001 Register VReg, MachineInstr::MIFlag Flags) const {
1002 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
1003
1004 // Callers may expect a single instruction, so keep 128-bit moves
1005 // together for now and lower them after register allocation.
1006 unsigned LoadOpcode, StoreOpcode;
1007 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode);
1008 addFrameReference(MIB: BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: StoreOpcode))
1009 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: isKill)),
1010 FI: FrameIdx);
1011}
1012
1013void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
1014 MachineBasicBlock::iterator MBBI,
1015 Register DestReg, int FrameIdx,
1016 const TargetRegisterClass *RC,
1017 Register VReg, unsigned SubReg,
1018 MachineInstr::MIFlag Flags) const {
1019 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
1020
1021 // Callers may expect a single instruction, so keep 128-bit moves
1022 // together for now and lower them after register allocation.
1023 unsigned LoadOpcode, StoreOpcode;
1024 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode);
1025 addFrameReference(MIB: BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: LoadOpcode), DestReg),
1026 FI: FrameIdx);
1027}
1028
1029// Return true if MI is a simple load or store with a 12-bit displacement
1030// and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores.
1031static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) {
1032 const MCInstrDesc &MCID = MI->getDesc();
1033 return ((MCID.TSFlags & Flag) &&
1034 isUInt<12>(x: MI->getOperand(i: 2).getImm()) &&
1035 MI->getOperand(i: 3).getReg() == 0);
1036}
1037
1038namespace {
1039
1040struct LogicOp {
1041 LogicOp() = default;
1042 LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize)
1043 : RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
1044
1045 explicit operator bool() const { return RegSize; }
1046
1047 unsigned RegSize = 0;
1048 unsigned ImmLSB = 0;
1049 unsigned ImmSize = 0;
1050};
1051
1052} // end anonymous namespace
1053
1054static LogicOp interpretAndImmediate(unsigned Opcode) {
1055 switch (Opcode) {
1056 case SystemZ::NILMux: return LogicOp(32, 0, 16);
1057 case SystemZ::NIHMux: return LogicOp(32, 16, 16);
1058 case SystemZ::NILL64: return LogicOp(64, 0, 16);
1059 case SystemZ::NILH64: return LogicOp(64, 16, 16);
1060 case SystemZ::NIHL64: return LogicOp(64, 32, 16);
1061 case SystemZ::NIHH64: return LogicOp(64, 48, 16);
1062 case SystemZ::NIFMux: return LogicOp(32, 0, 32);
1063 case SystemZ::NILF64: return LogicOp(64, 0, 32);
1064 case SystemZ::NIHF64: return LogicOp(64, 32, 32);
1065 default: return LogicOp();
1066 }
1067}
1068
1069static void transferDeadCC(MachineInstr *OldMI, MachineInstr *NewMI) {
1070 if (OldMI->registerDefIsDead(Reg: SystemZ::CC, /*TRI=*/nullptr)) {
1071 MachineOperand *CCDef =
1072 NewMI->findRegisterDefOperand(Reg: SystemZ::CC, /*TRI=*/nullptr);
1073 if (CCDef != nullptr)
1074 CCDef->setIsDead(true);
1075 }
1076}
1077
1078static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI,
1079 MachineInstr::MIFlag Flag) {
1080 if (OldMI->getFlag(Flag))
1081 NewMI->setFlag(Flag);
1082}
1083
1084MachineInstr *
1085SystemZInstrInfo::convertToThreeAddress(MachineInstr &MI,
1086 LiveIntervals *LIS) const {
1087 MachineBasicBlock *MBB = MI.getParent();
1088
1089 // Try to convert an AND into an RISBG-type instruction.
1090 // TODO: It might be beneficial to select RISBG and shorten to AND instead.
1091 if (LogicOp And = interpretAndImmediate(Opcode: MI.getOpcode())) {
1092 if (!MI.registerDefIsDead(Reg: SystemZ::CC, /*TRI=*/nullptr))
1093 return nullptr;
1094 uint64_t Imm = MI.getOperand(i: 2).getImm() << And.ImmLSB;
1095 // AND IMMEDIATE leaves the other bits of the register unchanged.
1096 Imm |= allOnes(Count: And.RegSize) & ~(allOnes(Count: And.ImmSize) << And.ImmLSB);
1097 unsigned Start, End;
1098 if (isRxSBGMask(Mask: Imm, BitSize: And.RegSize, Start, End)) {
1099 unsigned NewOpcode;
1100 if (And.RegSize == 64) {
1101 NewOpcode = SystemZ::RISBG;
1102 // Prefer RISBGN if available, since it does not clobber CC.
1103 if (STI.hasMiscellaneousExtensions())
1104 NewOpcode = SystemZ::RISBGN;
1105 } else {
1106 NewOpcode = SystemZ::RISBMux;
1107 Start &= 31;
1108 End &= 31;
1109 }
1110 MachineOperand &Dest = MI.getOperand(i: 0);
1111 MachineOperand &Src = MI.getOperand(i: 1);
1112 MachineInstrBuilder MIB =
1113 BuildMI(BB&: *MBB, I&: MI, MIMD: MI.getDebugLoc(), MCID: get(Opcode: NewOpcode))
1114 .add(MO: Dest)
1115 .addReg(RegNo: 0)
1116 .addReg(RegNo: Src.getReg(), Flags: getKillRegState(B: Src.isKill()),
1117 SubReg: Src.getSubReg())
1118 .addImm(Val: Start)
1119 .addImm(Val: End + 128)
1120 .addImm(Val: 0);
1121 if (LIS) {
1122 SlotIndex Idx = LIS->ReplaceMachineInstrInMaps(MI, NewMI&: *MIB);
1123 if (!MIB->definesRegister(Reg: SystemZ::CC, /*TRI=*/nullptr))
1124 LIS->removePhysRegDefAt(Reg: SystemZ::CC, Pos: Idx.getRegSlot());
1125 }
1126 transferDeadCC(OldMI: &MI, NewMI: MIB);
1127 return MIB;
1128 }
1129 }
1130 return nullptr;
1131}
1132
1133bool SystemZInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst,
1134 bool Invert) const {
1135 unsigned Opc = Inst.getOpcode();
1136 if (Invert) {
1137 auto InverseOpcode = getInverseOpcode(Opcode: Opc);
1138 if (!InverseOpcode)
1139 return false;
1140 Opc = *InverseOpcode;
1141 }
1142
1143 switch (Opc) {
1144 default:
1145 break;
1146 // Adds and multiplications.
1147 case SystemZ::WFADB:
1148 case SystemZ::WFASB:
1149 case SystemZ::WFAXB:
1150 case SystemZ::VFADB:
1151 case SystemZ::VFASB:
1152 case SystemZ::WFMDB:
1153 case SystemZ::WFMSB:
1154 case SystemZ::WFMXB:
1155 case SystemZ::VFMDB:
1156 case SystemZ::VFMSB:
1157 return (Inst.getFlag(Flag: MachineInstr::MIFlag::FmReassoc) &&
1158 Inst.getFlag(Flag: MachineInstr::MIFlag::FmNsz));
1159 }
1160
1161 return false;
1162}
1163
1164std::optional<unsigned>
1165SystemZInstrInfo::getInverseOpcode(unsigned Opcode) const {
1166 // fadd => fsub
1167 switch (Opcode) {
1168 case SystemZ::WFADB:
1169 return SystemZ::WFSDB;
1170 case SystemZ::WFASB:
1171 return SystemZ::WFSSB;
1172 case SystemZ::WFAXB:
1173 return SystemZ::WFSXB;
1174 case SystemZ::VFADB:
1175 return SystemZ::VFSDB;
1176 case SystemZ::VFASB:
1177 return SystemZ::VFSSB;
1178 // fsub => fadd
1179 case SystemZ::WFSDB:
1180 return SystemZ::WFADB;
1181 case SystemZ::WFSSB:
1182 return SystemZ::WFASB;
1183 case SystemZ::WFSXB:
1184 return SystemZ::WFAXB;
1185 case SystemZ::VFSDB:
1186 return SystemZ::VFADB;
1187 case SystemZ::VFSSB:
1188 return SystemZ::VFASB;
1189 default:
1190 return std::nullopt;
1191 }
1192}
1193
1194MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl(
1195 MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
1196 int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS,
1197 VirtRegMap *VRM) const {
1198 MachineBasicBlock::iterator InsertPt = MI;
1199 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
1200 MachineRegisterInfo &MRI = MF.getRegInfo();
1201 const MachineFrameInfo &MFI = MF.getFrameInfo();
1202 unsigned Size = MFI.getObjectSize(ObjectIdx: FrameIndex);
1203 unsigned Opcode = MI.getOpcode();
1204
1205 // Check CC liveness if new instruction introduces a dead def of CC.
1206 SlotIndex MISlot = SlotIndex();
1207 LiveRange *CCLiveRange = nullptr;
1208 bool CCLiveAtMI = true;
1209 if (LIS) {
1210 MISlot = LIS->getSlotIndexes()->getInstructionIndex(MI).getRegSlot();
1211 auto CCUnits = TRI->regunits(Reg: MCRegister::from(Val: SystemZ::CC));
1212 assert(range_size(CCUnits) == 1 && "CC only has one reg unit.");
1213 CCLiveRange = &LIS->getRegUnit(Unit: *CCUnits.begin());
1214 CCLiveAtMI = CCLiveRange->liveAt(index: MISlot);
1215 }
1216
1217 if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) {
1218 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1219 isInt<8>(x: MI.getOperand(i: 2).getImm()) && !MI.getOperand(i: 3).getReg()) {
1220 // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST
1221 MachineInstr *BuiltMI = BuildMI(BB&: *InsertPt->getParent(), I: InsertPt,
1222 MIMD: MI.getDebugLoc(), MCID: get(Opcode: SystemZ::AGSI))
1223 .addFrameIndex(Idx: FrameIndex)
1224 .addImm(Val: 0)
1225 .addImm(Val: MI.getOperand(i: 2).getImm());
1226 BuiltMI->findRegisterDefOperand(Reg: SystemZ::CC, /*TRI=*/nullptr)
1227 ->setIsDead(true);
1228 CCLiveRange->createDeadDef(Def: MISlot, VNIAlloc&: LIS->getVNInfoAllocator());
1229 return BuiltMI;
1230 }
1231 return nullptr;
1232 }
1233
1234 // All other cases require a single operand.
1235 if (Ops.size() != 1)
1236 return nullptr;
1237
1238 unsigned OpNum = Ops[0];
1239 const TargetRegisterClass *RC =
1240 MF.getRegInfo().getRegClass(Reg: MI.getOperand(i: OpNum).getReg());
1241 assert((Size * 8 == TRI->getRegSizeInBits(*RC) ||
1242 (RC == &SystemZ::FP16BitRegClass && Size == 4 && !STI.hasVector())) &&
1243 "Invalid size combination");
1244 (void)RC;
1245
1246 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1247 isInt<8>(x: MI.getOperand(i: 2).getImm())) {
1248 // A(G)HI %reg, CONST -> A(G)SI %mem, CONST
1249 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1250 MachineInstr *BuiltMI =
1251 BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(), MCID: get(Opcode))
1252 .addFrameIndex(Idx: FrameIndex)
1253 .addImm(Val: 0)
1254 .addImm(Val: MI.getOperand(i: 2).getImm());
1255 transferDeadCC(OldMI: &MI, NewMI: BuiltMI);
1256 transferMIFlag(OldMI: &MI, NewMI: BuiltMI, Flag: MachineInstr::NoSWrap);
1257 return BuiltMI;
1258 }
1259
1260 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1261 isInt<8>(x: (int32_t)MI.getOperand(i: 2).getImm())) ||
1262 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1263 isInt<8>(x: MI.getOperand(i: 2).getImm()))) {
1264 // AL(G)FI %reg, CONST -> AL(G)SI %mem, CONST
1265 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1266 MachineInstr *BuiltMI =
1267 BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(), MCID: get(Opcode))
1268 .addFrameIndex(Idx: FrameIndex)
1269 .addImm(Val: 0)
1270 .addImm(Val: (int8_t)MI.getOperand(i: 2).getImm());
1271 transferDeadCC(OldMI: &MI, NewMI: BuiltMI);
1272 return BuiltMI;
1273 }
1274
1275 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1276 isInt<8>(x: (int32_t)-MI.getOperand(i: 2).getImm())) ||
1277 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1278 isInt<8>(x: (-MI.getOperand(i: 2).getImm())))) {
1279 // SL(G)FI %reg, CONST -> AL(G)SI %mem, -CONST
1280 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1281 MachineInstr *BuiltMI =
1282 BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(), MCID: get(Opcode))
1283 .addFrameIndex(Idx: FrameIndex)
1284 .addImm(Val: 0)
1285 .addImm(Val: (int8_t)-MI.getOperand(i: 2).getImm());
1286 transferDeadCC(OldMI: &MI, NewMI: BuiltMI);
1287 return BuiltMI;
1288 }
1289
1290 unsigned MemImmOpc = 0;
1291 switch (Opcode) {
1292 case SystemZ::LHIMux:
1293 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI; break;
1294 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI; break;
1295 case SystemZ::CHIMux:
1296 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI; break;
1297 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI; break;
1298 case SystemZ::CLFIMux:
1299 case SystemZ::CLFI:
1300 if (isUInt<16>(x: MI.getOperand(i: 1).getImm()))
1301 MemImmOpc = SystemZ::CLFHSI;
1302 break;
1303 case SystemZ::CLGFI:
1304 if (isUInt<16>(x: MI.getOperand(i: 1).getImm()))
1305 MemImmOpc = SystemZ::CLGHSI;
1306 break;
1307 default: break;
1308 }
1309 if (MemImmOpc)
1310 return BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(),
1311 MCID: get(Opcode: MemImmOpc))
1312 .addFrameIndex(Idx: FrameIndex)
1313 .addImm(Val: 0)
1314 .addImm(Val: MI.getOperand(i: 1).getImm());
1315
1316 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1317 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1318 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1319 // If we're spilling the destination of an LDGR or LGDR, store the
1320 // source register instead.
1321 if (OpNum == 0) {
1322 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1323 return BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(),
1324 MCID: get(Opcode: StoreOpcode))
1325 .add(MO: MI.getOperand(i: 1))
1326 .addFrameIndex(Idx: FrameIndex)
1327 .addImm(Val: 0)
1328 .addReg(RegNo: 0);
1329 }
1330 // If we're spilling the source of an LDGR or LGDR, load the
1331 // destination register instead.
1332 if (OpNum == 1) {
1333 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1334 return BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(),
1335 MCID: get(Opcode: LoadOpcode))
1336 .add(MO: MI.getOperand(i: 0))
1337 .addFrameIndex(Idx: FrameIndex)
1338 .addImm(Val: 0)
1339 .addReg(RegNo: 0);
1340 }
1341 }
1342
1343 // Look for cases where the source of a simple store or the destination
1344 // of a simple load is being spilled. Try to use MVC instead.
1345 //
1346 // Although MVC is in practice a fast choice in these cases, it is still
1347 // logically a bytewise copy. This means that we cannot use it if the
1348 // load or store is volatile. We also wouldn't be able to use MVC if
1349 // the two memories partially overlap, but that case cannot occur here,
1350 // because we know that one of the memories is a full frame index.
1351 //
1352 // For performance reasons, we also want to avoid using MVC if the addresses
1353 // might be equal. We don't worry about that case here, because spill slot
1354 // coloring happens later, and because we have special code to remove
1355 // MVCs that turn out to be redundant.
1356 if (OpNum == 0 && MI.hasOneMemOperand()) {
1357 MachineMemOperand *MMO = *MI.memoperands_begin();
1358 if (MMO->getSize() == Size && !MMO->isVolatile() && !MMO->isAtomic()) {
1359 // Handle conversion of loads.
1360 if (isSimpleBD12Move(MI: &MI, Flag: SystemZII::SimpleBDXLoad)) {
1361 return BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(),
1362 MCID: get(Opcode: SystemZ::MVC))
1363 .addFrameIndex(Idx: FrameIndex)
1364 .addImm(Val: 0)
1365 .addImm(Val: Size)
1366 .add(MO: MI.getOperand(i: 1))
1367 .addImm(Val: MI.getOperand(i: 2).getImm())
1368 .addMemOperand(MMO);
1369 }
1370 // Handle conversion of stores.
1371 if (isSimpleBD12Move(MI: &MI, Flag: SystemZII::SimpleBDXStore)) {
1372 return BuildMI(BB&: *InsertPt->getParent(), I: InsertPt, MIMD: MI.getDebugLoc(),
1373 MCID: get(Opcode: SystemZ::MVC))
1374 .add(MO: MI.getOperand(i: 1))
1375 .addImm(Val: MI.getOperand(i: 2).getImm())
1376 .addImm(Val: Size)
1377 .addFrameIndex(Idx: FrameIndex)
1378 .addImm(Val: 0)
1379 .addMemOperand(MMO);
1380 }
1381 }
1382 }
1383
1384 // If the spilled operand is the final one or the instruction is
1385 // commutable, try to change <INSN>R into <INSN>. Don't introduce a def of
1386 // CC if it is live and MI does not define it.
1387 unsigned NumOps = MI.getNumExplicitOperands();
1388 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1389 if (MemOpcode == -1 ||
1390 (CCLiveAtMI && !MI.definesRegister(Reg: SystemZ::CC, /*TRI=*/nullptr) &&
1391 get(Opcode: MemOpcode).hasImplicitDefOfPhysReg(Reg: SystemZ::CC)))
1392 return nullptr;
1393
1394 // Check if all other vregs have a usable allocation in the case of vector
1395 // to FP conversion.
1396 const MCInstrDesc &MCID = MI.getDesc();
1397 for (unsigned I = 0, E = MCID.getNumOperands(); I != E; ++I) {
1398 const MCOperandInfo &MCOI = MCID.operands()[I];
1399 if (MCOI.OperandType != MCOI::OPERAND_REGISTER || I == OpNum)
1400 continue;
1401 const TargetRegisterClass *RC = TRI->getRegClass(i: MCOI.RegClass);
1402 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1403 Register Reg = MI.getOperand(i: I).getReg();
1404 Register PhysReg = Reg.isVirtual()
1405 ? (VRM ? Register(VRM->getPhys(virtReg: Reg)) : Register())
1406 : Reg;
1407 if (!PhysReg ||
1408 !(SystemZ::FP32BitRegClass.contains(Reg: PhysReg) ||
1409 SystemZ::FP64BitRegClass.contains(Reg: PhysReg) ||
1410 SystemZ::VF128BitRegClass.contains(Reg: PhysReg)))
1411 return nullptr;
1412 }
1413 }
1414 // Fused multiply and add/sub need to have the same dst and accumulator reg.
1415 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1416 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1417 if (FusedFPOp) {
1418 Register DstReg = VRM->getPhys(virtReg: MI.getOperand(i: 0).getReg());
1419 Register AccReg = VRM->getPhys(virtReg: MI.getOperand(i: 3).getReg());
1420 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1421 return nullptr;
1422 }
1423
1424 // Try to swap compare operands if possible.
1425 bool NeedsCommute = false;
1426 if ((MI.getOpcode() == SystemZ::CR || MI.getOpcode() == SystemZ::CGR ||
1427 MI.getOpcode() == SystemZ::CLR || MI.getOpcode() == SystemZ::CLGR ||
1428 MI.getOpcode() == SystemZ::WFCDB || MI.getOpcode() == SystemZ::WFCSB ||
1429 MI.getOpcode() == SystemZ::WFKDB || MI.getOpcode() == SystemZ::WFKSB) &&
1430 OpNum == 0 && prepareCompareSwapOperands(MBBI: MI))
1431 NeedsCommute = true;
1432
1433 bool CCOperands = false;
1434 if (MI.getOpcode() == SystemZ::LOCRMux || MI.getOpcode() == SystemZ::LOCGR ||
1435 MI.getOpcode() == SystemZ::SELRMux || MI.getOpcode() == SystemZ::SELGR) {
1436 assert(MI.getNumOperands() == 6 && NumOps == 5 &&
1437 "LOCR/SELR instruction operands corrupt?");
1438 NumOps -= 2;
1439 CCOperands = true;
1440 }
1441
1442 // See if this is a 3-address instruction that is convertible to 2-address
1443 // and suitable for folding below. Only try this with virtual registers
1444 // and a provided VRM (during regalloc).
1445 if (NumOps == 3 && SystemZ::getTargetMemOpcode(Opcode: MemOpcode) != -1) {
1446 if (VRM == nullptr)
1447 return nullptr;
1448 else {
1449 Register DstReg = MI.getOperand(i: 0).getReg();
1450 Register DstPhys =
1451 (DstReg.isVirtual() ? Register(VRM->getPhys(virtReg: DstReg)) : DstReg);
1452 Register SrcReg = (OpNum == 2 ? MI.getOperand(i: 1).getReg()
1453 : ((OpNum == 1 && MI.isCommutable())
1454 ? MI.getOperand(i: 2).getReg()
1455 : Register()));
1456 if (DstPhys && !SystemZ::GRH32BitRegClass.contains(Reg: DstPhys) && SrcReg &&
1457 SrcReg.isVirtual() && DstPhys == VRM->getPhys(virtReg: SrcReg))
1458 NeedsCommute = (OpNum == 1);
1459 else
1460 return nullptr;
1461 }
1462 }
1463
1464 if ((OpNum == NumOps - 1) || NeedsCommute || FusedFPOp) {
1465 const MCInstrDesc &MemDesc = get(Opcode: MemOpcode);
1466 uint64_t AccessBytes = SystemZII::getAccessSize(Flags: MemDesc.TSFlags);
1467 assert(AccessBytes != 0 && "Size of access should be known");
1468 assert(AccessBytes <= Size && "Access outside the frame index");
1469 uint64_t Offset = Size - AccessBytes;
1470 MachineInstrBuilder MIB = BuildMI(BB&: *InsertPt->getParent(), I: InsertPt,
1471 MIMD: MI.getDebugLoc(), MCID: get(Opcode: MemOpcode));
1472 if (MI.isCompare()) {
1473 assert(NumOps == 2 && "Expected 2 register operands for a compare.");
1474 MIB.add(MO: MI.getOperand(i: NeedsCommute ? 1 : 0));
1475 }
1476 else if (FusedFPOp) {
1477 MIB.add(MO: MI.getOperand(i: 0));
1478 MIB.add(MO: MI.getOperand(i: 3));
1479 MIB.add(MO: MI.getOperand(i: OpNum == 1 ? 2 : 1));
1480 }
1481 else {
1482 MIB.add(MO: MI.getOperand(i: 0));
1483 if (NeedsCommute)
1484 MIB.add(MO: MI.getOperand(i: 2));
1485 else
1486 for (unsigned I = 1; I < OpNum; ++I)
1487 MIB.add(MO: MI.getOperand(i: I));
1488 }
1489 MIB.addFrameIndex(Idx: FrameIndex).addImm(Val: Offset);
1490 if (MemDesc.TSFlags & SystemZII::HasIndex)
1491 MIB.addReg(RegNo: 0);
1492 if (CCOperands) {
1493 unsigned CCValid = MI.getOperand(i: NumOps).getImm();
1494 unsigned CCMask = MI.getOperand(i: NumOps + 1).getImm();
1495 MIB.addImm(Val: CCValid);
1496 MIB.addImm(Val: NeedsCommute ? CCMask ^ CCValid : CCMask);
1497 }
1498 if (MIB->definesRegister(Reg: SystemZ::CC, /*TRI=*/nullptr) &&
1499 (!MI.definesRegister(Reg: SystemZ::CC, /*TRI=*/nullptr) ||
1500 MI.registerDefIsDead(Reg: SystemZ::CC, /*TRI=*/nullptr))) {
1501 MIB->addRegisterDead(Reg: SystemZ::CC, RegInfo: TRI);
1502 if (CCLiveRange)
1503 CCLiveRange->createDeadDef(Def: MISlot, VNIAlloc&: LIS->getVNInfoAllocator());
1504 }
1505 // Constrain the register classes if converted from a vector opcode. The
1506 // allocated regs are in an FP reg-class per previous check above.
1507 for (const MachineOperand &MO : MIB->operands())
1508 if (MO.isReg() && MO.getReg().isVirtual()) {
1509 Register Reg = MO.getReg();
1510 if (MRI.getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1511 MRI.setRegClass(Reg, RC: &SystemZ::FP32BitRegClass);
1512 else if (MRI.getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1513 MRI.setRegClass(Reg, RC: &SystemZ::FP64BitRegClass);
1514 else if (MRI.getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1515 MRI.setRegClass(Reg, RC: &SystemZ::VF128BitRegClass);
1516 }
1517
1518 transferDeadCC(OldMI: &MI, NewMI: MIB);
1519 transferMIFlag(OldMI: &MI, NewMI: MIB, Flag: MachineInstr::NoSWrap);
1520 transferMIFlag(OldMI: &MI, NewMI: MIB, Flag: MachineInstr::NoFPExcept);
1521 return MIB;
1522 }
1523
1524 return nullptr;
1525}
1526
1527MachineInstr *SystemZInstrInfo::foldMemoryOperandImpl(
1528 MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
1529 MachineInstr &LoadMI, MachineInstr *&CopyMI, LiveIntervals *LIS,
1530 VirtRegMap *VRM) const {
1531 MachineBasicBlock::iterator InsertPt = MI;
1532 MachineRegisterInfo *MRI = &MF.getRegInfo();
1533 MachineBasicBlock *MBB = MI.getParent();
1534
1535 // For reassociable FP operations, any loads have been purposefully left
1536 // unfolded so that MachineCombiner can do its work on reg/reg
1537 // opcodes. After that, as many loads as possible are now folded.
1538 // TODO: This may be beneficial with other opcodes as well as machine-sink
1539 // can move loads close to their user in a different MBB, which the isel
1540 // matcher did not see.
1541 unsigned LoadOpc = 0;
1542 unsigned RegMemOpcode = 0;
1543 const TargetRegisterClass *FPRC = nullptr;
1544 RegMemOpcode = MI.getOpcode() == SystemZ::WFADB ? SystemZ::ADB
1545 : MI.getOpcode() == SystemZ::WFSDB ? SystemZ::SDB
1546 : MI.getOpcode() == SystemZ::WFMDB ? SystemZ::MDB
1547 : 0;
1548 if (RegMemOpcode) {
1549 LoadOpc = SystemZ::VL64;
1550 FPRC = &SystemZ::FP64BitRegClass;
1551 } else {
1552 RegMemOpcode = MI.getOpcode() == SystemZ::WFASB ? SystemZ::AEB
1553 : MI.getOpcode() == SystemZ::WFSSB ? SystemZ::SEB
1554 : MI.getOpcode() == SystemZ::WFMSB ? SystemZ::MEEB
1555 : 0;
1556 if (RegMemOpcode) {
1557 LoadOpc = SystemZ::VL32;
1558 FPRC = &SystemZ::FP32BitRegClass;
1559 }
1560 }
1561 if (!RegMemOpcode || LoadMI.getOpcode() != LoadOpc)
1562 return nullptr;
1563
1564 // If RegMemOpcode clobbers CC, first make sure CC is not live at this point.
1565 if (get(Opcode: RegMemOpcode).hasImplicitDefOfPhysReg(Reg: SystemZ::CC)) {
1566 for (MachineBasicBlock::iterator MII = InsertPt;;) {
1567 if (MII == MBB->begin()) {
1568 if (MBB->isLiveIn(Reg: SystemZ::CC))
1569 return nullptr;
1570 break;
1571 }
1572 --MII;
1573 if (MII->definesRegister(Reg: SystemZ::CC, /*TRI=*/nullptr)) {
1574 if (!MII->registerDefIsDead(Reg: SystemZ::CC, /*TRI=*/nullptr))
1575 return nullptr;
1576 break;
1577 }
1578 }
1579 }
1580
1581 Register FoldAsLoadDefReg = LoadMI.getOperand(i: 0).getReg();
1582 if (Ops.size() != 1 || FoldAsLoadDefReg != MI.getOperand(i: Ops[0]).getReg())
1583 return nullptr;
1584 Register DstReg = MI.getOperand(i: 0).getReg();
1585 MachineOperand LHS = MI.getOperand(i: 1);
1586 MachineOperand RHS = MI.getOperand(i: 2);
1587 MachineOperand &RegMO = RHS.getReg() == FoldAsLoadDefReg ? LHS : RHS;
1588 if ((RegMemOpcode == SystemZ::SDB || RegMemOpcode == SystemZ::SEB) &&
1589 FoldAsLoadDefReg != RHS.getReg())
1590 return nullptr;
1591 if (!MRI->isSSA() && DstReg != RegMO.getReg())
1592 return nullptr;
1593
1594 MachineOperand &Base = LoadMI.getOperand(i: 1);
1595 MachineOperand &Disp = LoadMI.getOperand(i: 2);
1596 MachineOperand &Indx = LoadMI.getOperand(i: 3);
1597 MachineInstrBuilder MIB =
1598 BuildMI(BB&: *MI.getParent(), I: InsertPt, MIMD: MI.getDebugLoc(), MCID: get(Opcode: RegMemOpcode), DestReg: DstReg)
1599 .add(MO: RegMO)
1600 .add(MO: Base)
1601 .add(MO: Disp)
1602 .add(MO: Indx);
1603 MIB->addRegisterDead(Reg: SystemZ::CC, RegInfo: &RI);
1604 MRI->setRegClass(Reg: DstReg, RC: FPRC);
1605 MRI->setRegClass(Reg: RegMO.getReg(), RC: FPRC);
1606 transferMIFlag(OldMI: &MI, NewMI: MIB, Flag: MachineInstr::NoFPExcept);
1607
1608 return MIB;
1609}
1610
1611bool SystemZInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
1612 switch (MI.getOpcode()) {
1613 case SystemZ::L128:
1614 splitMove(MI, NewOpcode: SystemZ::LG);
1615 return true;
1616
1617 case SystemZ::ST128:
1618 splitMove(MI, NewOpcode: SystemZ::STG);
1619 return true;
1620
1621 case SystemZ::LX:
1622 splitMove(MI, NewOpcode: SystemZ::LD);
1623 return true;
1624
1625 case SystemZ::STX:
1626 splitMove(MI, NewOpcode: SystemZ::STD);
1627 return true;
1628
1629 case SystemZ::LBMux:
1630 expandRXYPseudo(MI, LowOpcode: SystemZ::LB, HighOpcode: SystemZ::LBH);
1631 return true;
1632
1633 case SystemZ::LHMux:
1634 expandRXYPseudo(MI, LowOpcode: SystemZ::LH, HighOpcode: SystemZ::LHH);
1635 return true;
1636
1637 case SystemZ::LLCRMux:
1638 expandZExtPseudo(MI, LowOpcode: SystemZ::LLCR, Size: 8);
1639 return true;
1640
1641 case SystemZ::LLHRMux:
1642 expandZExtPseudo(MI, LowOpcode: SystemZ::LLHR, Size: 16);
1643 return true;
1644
1645 case SystemZ::LLCMux:
1646 expandRXYPseudo(MI, LowOpcode: SystemZ::LLC, HighOpcode: SystemZ::LLCH);
1647 return true;
1648
1649 case SystemZ::LLHMux:
1650 expandRXYPseudo(MI, LowOpcode: SystemZ::LLH, HighOpcode: SystemZ::LLHH);
1651 return true;
1652
1653 case SystemZ::LMux:
1654 expandRXYPseudo(MI, LowOpcode: SystemZ::L, HighOpcode: SystemZ::LFH);
1655 return true;
1656
1657 case SystemZ::LOCMux:
1658 expandLOCPseudo(MI, LowOpcode: SystemZ::LOC, HighOpcode: SystemZ::LOCFH);
1659 return true;
1660
1661 case SystemZ::LOCHIMux:
1662 expandLOCPseudo(MI, LowOpcode: SystemZ::LOCHI, HighOpcode: SystemZ::LOCHHI);
1663 return true;
1664
1665 case SystemZ::STCMux:
1666 expandRXYPseudo(MI, LowOpcode: SystemZ::STC, HighOpcode: SystemZ::STCH);
1667 return true;
1668
1669 case SystemZ::STHMux:
1670 expandRXYPseudo(MI, LowOpcode: SystemZ::STH, HighOpcode: SystemZ::STHH);
1671 return true;
1672
1673 case SystemZ::STMux:
1674 expandRXYPseudo(MI, LowOpcode: SystemZ::ST, HighOpcode: SystemZ::STFH);
1675 return true;
1676
1677 case SystemZ::STOCMux:
1678 expandLOCPseudo(MI, LowOpcode: SystemZ::STOC, HighOpcode: SystemZ::STOCFH);
1679 return true;
1680
1681 case SystemZ::LHIMux:
1682 expandRIPseudo(MI, LowOpcode: SystemZ::LHI, HighOpcode: SystemZ::IIHF, ConvertHigh: true);
1683 return true;
1684
1685 case SystemZ::IIFMux:
1686 expandRIPseudo(MI, LowOpcode: SystemZ::IILF, HighOpcode: SystemZ::IIHF, ConvertHigh: false);
1687 return true;
1688
1689 case SystemZ::IILMux:
1690 expandRIPseudo(MI, LowOpcode: SystemZ::IILL, HighOpcode: SystemZ::IIHL, ConvertHigh: false);
1691 return true;
1692
1693 case SystemZ::IIHMux:
1694 expandRIPseudo(MI, LowOpcode: SystemZ::IILH, HighOpcode: SystemZ::IIHH, ConvertHigh: false);
1695 return true;
1696
1697 case SystemZ::NIFMux:
1698 expandRIPseudo(MI, LowOpcode: SystemZ::NILF, HighOpcode: SystemZ::NIHF, ConvertHigh: false);
1699 return true;
1700
1701 case SystemZ::NILMux:
1702 expandRIPseudo(MI, LowOpcode: SystemZ::NILL, HighOpcode: SystemZ::NIHL, ConvertHigh: false);
1703 return true;
1704
1705 case SystemZ::NIHMux:
1706 expandRIPseudo(MI, LowOpcode: SystemZ::NILH, HighOpcode: SystemZ::NIHH, ConvertHigh: false);
1707 return true;
1708
1709 case SystemZ::OIFMux:
1710 expandRIPseudo(MI, LowOpcode: SystemZ::OILF, HighOpcode: SystemZ::OIHF, ConvertHigh: false);
1711 return true;
1712
1713 case SystemZ::OILMux:
1714 expandRIPseudo(MI, LowOpcode: SystemZ::OILL, HighOpcode: SystemZ::OIHL, ConvertHigh: false);
1715 return true;
1716
1717 case SystemZ::OIHMux:
1718 expandRIPseudo(MI, LowOpcode: SystemZ::OILH, HighOpcode: SystemZ::OIHH, ConvertHigh: false);
1719 return true;
1720
1721 case SystemZ::XIFMux:
1722 expandRIPseudo(MI, LowOpcode: SystemZ::XILF, HighOpcode: SystemZ::XIHF, ConvertHigh: false);
1723 return true;
1724
1725 case SystemZ::TMLMux:
1726 expandRIPseudo(MI, LowOpcode: SystemZ::TMLL, HighOpcode: SystemZ::TMHL, ConvertHigh: false);
1727 return true;
1728
1729 case SystemZ::TMHMux:
1730 expandRIPseudo(MI, LowOpcode: SystemZ::TMLH, HighOpcode: SystemZ::TMHH, ConvertHigh: false);
1731 return true;
1732
1733 case SystemZ::AHIMux:
1734 expandRIPseudo(MI, LowOpcode: SystemZ::AHI, HighOpcode: SystemZ::AIH, ConvertHigh: false);
1735 return true;
1736
1737 case SystemZ::AHIMuxK:
1738 expandRIEPseudo(MI, LowOpcode: SystemZ::AHI, LowOpcodeK: SystemZ::AHIK, HighOpcode: SystemZ::AIH);
1739 return true;
1740
1741 case SystemZ::AFIMux:
1742 expandRIPseudo(MI, LowOpcode: SystemZ::AFI, HighOpcode: SystemZ::AIH, ConvertHigh: false);
1743 return true;
1744
1745 case SystemZ::CHIMux:
1746 expandRIPseudo(MI, LowOpcode: SystemZ::CHI, HighOpcode: SystemZ::CIH, ConvertHigh: false);
1747 return true;
1748
1749 case SystemZ::CFIMux:
1750 expandRIPseudo(MI, LowOpcode: SystemZ::CFI, HighOpcode: SystemZ::CIH, ConvertHigh: false);
1751 return true;
1752
1753 case SystemZ::CLFIMux:
1754 expandRIPseudo(MI, LowOpcode: SystemZ::CLFI, HighOpcode: SystemZ::CLIH, ConvertHigh: false);
1755 return true;
1756
1757 case SystemZ::CMux:
1758 expandRXYPseudo(MI, LowOpcode: SystemZ::C, HighOpcode: SystemZ::CHF);
1759 return true;
1760
1761 case SystemZ::CLMux:
1762 expandRXYPseudo(MI, LowOpcode: SystemZ::CL, HighOpcode: SystemZ::CLHF);
1763 return true;
1764
1765 case SystemZ::RISBMux: {
1766 bool DestIsHigh = SystemZ::isHighReg(Reg: MI.getOperand(i: 0).getReg());
1767 bool SrcIsHigh = SystemZ::isHighReg(Reg: MI.getOperand(i: 2).getReg());
1768 if (SrcIsHigh == DestIsHigh)
1769 MI.setDesc(get(Opcode: DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1770 else {
1771 MI.setDesc(get(Opcode: DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1772 MI.getOperand(i: 5).setImm(MI.getOperand(i: 5).getImm() ^ 32);
1773 }
1774 return true;
1775 }
1776
1777 case SystemZ::ADJDYNALLOC:
1778 splitAdjDynAlloc(MI);
1779 return true;
1780
1781 case SystemZ::MOV_STACKGUARD:
1782 expandStackGuardPseudo(MI, Opcode: SystemZ::MVC);
1783 return true;
1784
1785 case SystemZ::CMP_STACKGUARD:
1786 expandStackGuardPseudo(MI, Opcode: SystemZ::CLC);
1787 return true;
1788
1789 default:
1790 return false;
1791 }
1792}
1793
1794void SystemZInstrInfo::expandStackGuardPseudo(MachineInstr &MI,
1795 unsigned Opcode) const {
1796 MachineBasicBlock &MBB = *(MI.getParent());
1797 const MachineFunction &MF = *(MBB.getParent());
1798 const auto DL = MI.getDebugLoc();
1799 const Module *M = MF.getFunction().getParent();
1800 StringRef GuardType = M->getStackProtectorGuard();
1801 unsigned int Offset = 0;
1802
1803 Register AddrReg = MI.getOperand(i: 0).getReg();
1804
1805 assert(
1806 AddrReg != MI.getOperand(1).getReg() &&
1807 "Scratch register for stack guard address blocked by operand register.");
1808
1809 // Emit an appropriate pseudo for the guard type, which loads the address of
1810 // said guard into the scratch register AddrReg.
1811 if (GuardType.empty() || (GuardType == "tls")) {
1812 if (STI.isTargetzOS()) {
1813 enum { OFFSET_PSALAA = 0x4B8 };
1814 enum { OFFSET_CEELAA_STACK_GUARD = 0x98 };
1815 // Load LAA
1816 // LLGT <reg>,1208
1817 BuildMI(BB&: MBB, I&: MI, MIMD: MI.getDebugLoc(), MCID: get(Opcode: SystemZ::LLGT), DestReg: AddrReg)
1818 .addReg(RegNo: 0)
1819 .addImm(Val: OFFSET_PSALAA)
1820 .addReg(RegNo: 0);
1821 Offset = OFFSET_CEELAA_STACK_GUARD;
1822 } else {
1823 // Emit a load of the TLS block's address
1824 BuildMI(BB&: MBB, I&: MI, MIMD: DL, MCID: get(Opcode: SystemZ::LOAD_TLS_BLOCK_ADDR), DestReg: AddrReg);
1825 // Record the appropriate stack guard offset (40 in the tls case).
1826 Offset = 40;
1827 }
1828 } else if (GuardType == "global") {
1829 // Emit a load of the global stack guard's address
1830 BuildMI(BB&: MBB, I&: MI, MIMD: DL, MCID: get(Opcode: SystemZ::LOAD_GLOBAL_STACKGUARD_ADDR), DestReg: AddrReg);
1831 } else {
1832 report_fatal_error(reason: Twine("unknown stack protector type \"") + GuardType +
1833 "\".");
1834 }
1835
1836 // Construct the appropriate move or compare instruction using the
1837 // scratch register.
1838 BuildMI(BB&: *(MI.getParent()), I&: MI, MIMD: MI.getDebugLoc(), MCID: get(Opcode))
1839 .addReg(RegNo: MI.getOperand(i: 1).getReg())
1840 .addImm(Val: MI.getOperand(i: 2).getImm())
1841 .addImm(Val: 8)
1842 .addReg(RegNo: AddrReg)
1843 .addImm(Val: Offset);
1844
1845 MI.removeFromParent();
1846}
1847
1848unsigned SystemZInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
1849 if (MI.isInlineAsm()) {
1850 const MachineFunction *MF = MI.getParent()->getParent();
1851 const char *AsmStr = MI.getOperand(i: 0).getSymbolName();
1852 return getInlineAsmLength(Str: AsmStr, MAI: MF->getTarget().getMCAsmInfo());
1853 }
1854 else if (MI.getOpcode() == SystemZ::PATCHPOINT)
1855 return PatchPointOpers(&MI).getNumPatchBytes();
1856 else if (MI.getOpcode() == SystemZ::STACKMAP)
1857 return MI.getOperand(i: 1).getImm();
1858 else if (MI.getOpcode() == SystemZ::FENTRY_CALL)
1859 return 6;
1860 if (MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER)
1861 return 18;
1862 if (MI.getOpcode() == TargetOpcode::PATCHABLE_RET)
1863 return 18 + (MI.getOperand(i: 0).getImm() == SystemZ::CondReturn ? 4 : 0);
1864 if (MI.getOpcode() == TargetOpcode::BUNDLE)
1865 return getInstBundleSize(MI);
1866 if (MI.getOpcode() == SystemZ::LOAD_TLS_BLOCK_ADDR)
1867 // ear (4), sllg (6), ear (4) = 14 bytes
1868 return 14;
1869 if (MI.getOpcode() == SystemZ::LOAD_GLOBAL_STACKGUARD_ADDR)
1870 // Both larl and lgrl are 6 bytes long.
1871 return 6;
1872
1873 return MI.getDesc().getSize();
1874}
1875
1876SystemZII::Branch
1877SystemZInstrInfo::getBranchInfo(const MachineInstr &MI) const {
1878 switch (MI.getOpcode()) {
1879 case SystemZ::BR:
1880 case SystemZ::BI:
1881 case SystemZ::J:
1882 case SystemZ::JG:
1883 return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY,
1884 SystemZ::CCMASK_ANY, &MI.getOperand(i: 0));
1885
1886 case SystemZ::BRC:
1887 case SystemZ::BRCL:
1888 return SystemZII::Branch(SystemZII::BranchNormal, MI.getOperand(i: 0).getImm(),
1889 MI.getOperand(i: 1).getImm(), &MI.getOperand(i: 2));
1890
1891 case SystemZ::BRCT:
1892 case SystemZ::BRCTH:
1893 return SystemZII::Branch(SystemZII::BranchCT, SystemZ::CCMASK_ICMP,
1894 SystemZ::CCMASK_CMP_NE, &MI.getOperand(i: 2));
1895
1896 case SystemZ::BRCTG:
1897 return SystemZII::Branch(SystemZII::BranchCTG, SystemZ::CCMASK_ICMP,
1898 SystemZ::CCMASK_CMP_NE, &MI.getOperand(i: 2));
1899
1900 case SystemZ::CIJ:
1901 case SystemZ::CRJ:
1902 return SystemZII::Branch(SystemZII::BranchC, SystemZ::CCMASK_ICMP,
1903 MI.getOperand(i: 2).getImm(), &MI.getOperand(i: 3));
1904
1905 case SystemZ::CLIJ:
1906 case SystemZ::CLRJ:
1907 return SystemZII::Branch(SystemZII::BranchCL, SystemZ::CCMASK_ICMP,
1908 MI.getOperand(i: 2).getImm(), &MI.getOperand(i: 3));
1909
1910 case SystemZ::CGIJ:
1911 case SystemZ::CGRJ:
1912 return SystemZII::Branch(SystemZII::BranchCG, SystemZ::CCMASK_ICMP,
1913 MI.getOperand(i: 2).getImm(), &MI.getOperand(i: 3));
1914
1915 case SystemZ::CLGIJ:
1916 case SystemZ::CLGRJ:
1917 return SystemZII::Branch(SystemZII::BranchCLG, SystemZ::CCMASK_ICMP,
1918 MI.getOperand(i: 2).getImm(), &MI.getOperand(i: 3));
1919
1920 case SystemZ::INLINEASM_BR:
1921 // Don't try to analyze asm goto, so pass nullptr as branch target argument.
1922 return SystemZII::Branch(SystemZII::AsmGoto, 0, 0, nullptr);
1923
1924 default:
1925 llvm_unreachable("Unrecognized branch opcode");
1926 }
1927}
1928
1929void SystemZInstrInfo::getLoadStoreOpcodes(const TargetRegisterClass *RC,
1930 unsigned &LoadOpcode,
1931 unsigned &StoreOpcode) const {
1932 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1933 LoadOpcode = SystemZ::L;
1934 StoreOpcode = SystemZ::ST;
1935 } else if (RC == &SystemZ::GRH32BitRegClass) {
1936 LoadOpcode = SystemZ::LFH;
1937 StoreOpcode = SystemZ::STFH;
1938 } else if (RC == &SystemZ::GRX32BitRegClass) {
1939 LoadOpcode = SystemZ::LMux;
1940 StoreOpcode = SystemZ::STMux;
1941 } else if (RC == &SystemZ::GR64BitRegClass ||
1942 RC == &SystemZ::ADDR64BitRegClass) {
1943 LoadOpcode = SystemZ::LG;
1944 StoreOpcode = SystemZ::STG;
1945 } else if (RC == &SystemZ::GR128BitRegClass ||
1946 RC == &SystemZ::ADDR128BitRegClass) {
1947 LoadOpcode = SystemZ::L128;
1948 StoreOpcode = SystemZ::ST128;
1949 } else if (RC == &SystemZ::FP16BitRegClass && !STI.hasVector()) {
1950 LoadOpcode = SystemZ::LE16;
1951 StoreOpcode = SystemZ::STE16;
1952 } else if (RC == &SystemZ::FP32BitRegClass) {
1953 LoadOpcode = SystemZ::LE;
1954 StoreOpcode = SystemZ::STE;
1955 } else if (RC == &SystemZ::FP64BitRegClass) {
1956 LoadOpcode = SystemZ::LD;
1957 StoreOpcode = SystemZ::STD;
1958 } else if (RC == &SystemZ::FP128BitRegClass) {
1959 LoadOpcode = SystemZ::LX;
1960 StoreOpcode = SystemZ::STX;
1961 } else if (RC == &SystemZ::FP16BitRegClass ||
1962 RC == &SystemZ::VR16BitRegClass) {
1963 LoadOpcode = SystemZ::VL16;
1964 StoreOpcode = SystemZ::VST16;
1965 } else if (RC == &SystemZ::VR32BitRegClass) {
1966 LoadOpcode = SystemZ::VL32;
1967 StoreOpcode = SystemZ::VST32;
1968 } else if (RC == &SystemZ::VR64BitRegClass) {
1969 LoadOpcode = SystemZ::VL64;
1970 StoreOpcode = SystemZ::VST64;
1971 } else if (RC == &SystemZ::VF128BitRegClass ||
1972 RC == &SystemZ::VR128BitRegClass) {
1973 LoadOpcode = SystemZ::VL;
1974 StoreOpcode = SystemZ::VST;
1975 } else
1976 llvm_unreachable("Unsupported regclass to load or store");
1977}
1978
1979unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode,
1980 int64_t Offset,
1981 const MachineInstr *MI) const {
1982 const MCInstrDesc &MCID = get(Opcode);
1983 int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset);
1984 if (isUInt<12>(x: Offset) && isUInt<12>(x: Offset2)) {
1985 // Get the instruction to use for unsigned 12-bit displacements.
1986 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1987 if (Disp12Opcode >= 0)
1988 return Disp12Opcode;
1989
1990 // All address-related instructions can use unsigned 12-bit
1991 // displacements.
1992 return Opcode;
1993 }
1994 if (isInt<20>(x: Offset) && isInt<20>(x: Offset2)) {
1995 // Get the instruction to use for signed 20-bit displacements.
1996 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1997 if (Disp20Opcode >= 0)
1998 return Disp20Opcode;
1999
2000 // Check whether Opcode allows signed 20-bit displacements.
2001 if (MCID.TSFlags & SystemZII::Has20BitOffset)
2002 return Opcode;
2003
2004 // If a VR32/VR64 reg ended up in an FP register, use the FP opcode.
2005 if (MI && MI->getOperand(i: 0).isReg()) {
2006 Register Reg = MI->getOperand(i: 0).getReg();
2007 if (Reg.isPhysical() && SystemZMC::getFirstReg(Reg) < 16) {
2008 switch (Opcode) {
2009 case SystemZ::VL32:
2010 return SystemZ::LEY;
2011 case SystemZ::VST32:
2012 return SystemZ::STEY;
2013 case SystemZ::VL64:
2014 return SystemZ::LDY;
2015 case SystemZ::VST64:
2016 return SystemZ::STDY;
2017 default: break;
2018 }
2019 }
2020 }
2021 }
2022 return 0;
2023}
2024
2025bool SystemZInstrInfo::hasDisplacementPairInsn(unsigned Opcode) const {
2026 const MCInstrDesc &MCID = get(Opcode);
2027 if (MCID.TSFlags & SystemZII::Has20BitOffset)
2028 return SystemZ::getDisp12Opcode(Opcode) >= 0;
2029 return SystemZ::getDisp20Opcode(Opcode) >= 0;
2030}
2031
2032unsigned SystemZInstrInfo::getLoadAndTest(unsigned Opcode) const {
2033 switch (Opcode) {
2034 case SystemZ::L: return SystemZ::LT;
2035 case SystemZ::LY: return SystemZ::LT;
2036 case SystemZ::LG: return SystemZ::LTG;
2037 case SystemZ::LGF: return SystemZ::LTGF;
2038 case SystemZ::LR: return SystemZ::LTR;
2039 case SystemZ::LGFR: return SystemZ::LTGFR;
2040 case SystemZ::LGR: return SystemZ::LTGR;
2041 case SystemZ::LCDFR: return SystemZ::LCDBR;
2042 case SystemZ::LPDFR: return SystemZ::LPDBR;
2043 case SystemZ::LNDFR: return SystemZ::LNDBR;
2044 case SystemZ::LCDFR_32: return SystemZ::LCEBR;
2045 case SystemZ::LPDFR_32: return SystemZ::LPEBR;
2046 case SystemZ::LNDFR_32: return SystemZ::LNEBR;
2047 // On zEC12 we prefer to use RISBGN. But if there is a chance to
2048 // actually use the condition code, we may turn it back into RISGB.
2049 // Note that RISBG is not really a "load-and-test" instruction,
2050 // but sets the same condition code values, so is OK to use here.
2051 case SystemZ::RISBGN: return SystemZ::RISBG;
2052 default: return 0;
2053 }
2054}
2055
2056bool SystemZInstrInfo::isRxSBGMask(uint64_t Mask, unsigned BitSize,
2057 unsigned &Start, unsigned &End) const {
2058 // Reject trivial all-zero masks.
2059 Mask &= allOnes(Count: BitSize);
2060 if (Mask == 0)
2061 return false;
2062
2063 // Handle the 1+0+ or 0+1+0* cases. Start then specifies the index of
2064 // the msb and End specifies the index of the lsb.
2065 unsigned LSB, Length;
2066 if (isShiftedMask_64(Value: Mask, MaskIdx&: LSB, MaskLen&: Length)) {
2067 Start = 63 - (LSB + Length - 1);
2068 End = 63 - LSB;
2069 return true;
2070 }
2071
2072 // Handle the wrap-around 1+0+1+ cases. Start then specifies the msb
2073 // of the low 1s and End specifies the lsb of the high 1s.
2074 if (isShiftedMask_64(Value: Mask ^ allOnes(Count: BitSize), MaskIdx&: LSB, MaskLen&: Length)) {
2075 assert(LSB > 0 && "Bottom bit must be set");
2076 assert(LSB + Length < BitSize && "Top bit must be set");
2077 Start = 63 - (LSB - 1);
2078 End = 63 - (LSB + Length);
2079 return true;
2080 }
2081
2082 return false;
2083}
2084
2085unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
2086 SystemZII::FusedCompareType Type,
2087 const MachineInstr *MI) const {
2088 switch (Opcode) {
2089 case SystemZ::CHI:
2090 case SystemZ::CGHI:
2091 if (!(MI && isInt<8>(x: MI->getOperand(i: 1).getImm())))
2092 return 0;
2093 break;
2094 case SystemZ::CLFI:
2095 case SystemZ::CLGFI:
2096 if (!(MI && isUInt<8>(x: MI->getOperand(i: 1).getImm())))
2097 return 0;
2098 break;
2099 case SystemZ::CL:
2100 case SystemZ::CLG:
2101 if (!STI.hasMiscellaneousExtensions())
2102 return 0;
2103 if (!(MI && MI->getOperand(i: 3).getReg() == 0))
2104 return 0;
2105 break;
2106 }
2107 switch (Type) {
2108 case SystemZII::CompareAndBranch:
2109 switch (Opcode) {
2110 case SystemZ::CR:
2111 return SystemZ::CRJ;
2112 case SystemZ::CGR:
2113 return SystemZ::CGRJ;
2114 case SystemZ::CHI:
2115 return SystemZ::CIJ;
2116 case SystemZ::CGHI:
2117 return SystemZ::CGIJ;
2118 case SystemZ::CLR:
2119 return SystemZ::CLRJ;
2120 case SystemZ::CLGR:
2121 return SystemZ::CLGRJ;
2122 case SystemZ::CLFI:
2123 return SystemZ::CLIJ;
2124 case SystemZ::CLGFI:
2125 return SystemZ::CLGIJ;
2126 default:
2127 return 0;
2128 }
2129 case SystemZII::CompareAndReturn:
2130 switch (Opcode) {
2131 case SystemZ::CR:
2132 return SystemZ::CRBReturn;
2133 case SystemZ::CGR:
2134 return SystemZ::CGRBReturn;
2135 case SystemZ::CHI:
2136 return SystemZ::CIBReturn;
2137 case SystemZ::CGHI:
2138 return SystemZ::CGIBReturn;
2139 case SystemZ::CLR:
2140 return SystemZ::CLRBReturn;
2141 case SystemZ::CLGR:
2142 return SystemZ::CLGRBReturn;
2143 case SystemZ::CLFI:
2144 return SystemZ::CLIBReturn;
2145 case SystemZ::CLGFI:
2146 return SystemZ::CLGIBReturn;
2147 default:
2148 return 0;
2149 }
2150 case SystemZII::CompareAndSibcall:
2151 switch (Opcode) {
2152 case SystemZ::CR:
2153 return SystemZ::CRBCall;
2154 case SystemZ::CGR:
2155 return SystemZ::CGRBCall;
2156 case SystemZ::CHI:
2157 return SystemZ::CIBCall;
2158 case SystemZ::CGHI:
2159 return SystemZ::CGIBCall;
2160 case SystemZ::CLR:
2161 return SystemZ::CLRBCall;
2162 case SystemZ::CLGR:
2163 return SystemZ::CLGRBCall;
2164 case SystemZ::CLFI:
2165 return SystemZ::CLIBCall;
2166 case SystemZ::CLGFI:
2167 return SystemZ::CLGIBCall;
2168 default:
2169 return 0;
2170 }
2171 case SystemZII::CompareAndTrap:
2172 switch (Opcode) {
2173 case SystemZ::CR:
2174 return SystemZ::CRT;
2175 case SystemZ::CGR:
2176 return SystemZ::CGRT;
2177 case SystemZ::CHI:
2178 return SystemZ::CIT;
2179 case SystemZ::CGHI:
2180 return SystemZ::CGIT;
2181 case SystemZ::CLR:
2182 return SystemZ::CLRT;
2183 case SystemZ::CLGR:
2184 return SystemZ::CLGRT;
2185 case SystemZ::CLFI:
2186 return SystemZ::CLFIT;
2187 case SystemZ::CLGFI:
2188 return SystemZ::CLGIT;
2189 case SystemZ::CL:
2190 return SystemZ::CLT;
2191 case SystemZ::CLG:
2192 return SystemZ::CLGT;
2193 default:
2194 return 0;
2195 }
2196 }
2197 return 0;
2198}
2199
2200bool SystemZInstrInfo::isLoadAndTestAsCmp(const MachineInstr &MI) const {
2201 // If we during isel used a load-and-test as a compare with 0, the
2202 // def operand is dead.
2203 return (MI.getOpcode() == SystemZ::LTEBR ||
2204 MI.getOpcode() == SystemZ::LTDBR ||
2205 MI.getOpcode() == SystemZ::LTXBR) &&
2206 MI.getOperand(i: 0).isDead();
2207}
2208
2209bool SystemZInstrInfo::isCompareZero(const MachineInstr &Compare) const {
2210 if (isLoadAndTestAsCmp(MI: Compare))
2211 return true;
2212 return Compare.isCompare() && Compare.getNumExplicitOperands() == 2 &&
2213 Compare.getOperand(i: 1).isImm() && Compare.getOperand(i: 1).getImm() == 0;
2214}
2215
2216Register
2217SystemZInstrInfo::getCompareSourceReg(const MachineInstr &Compare) const {
2218 assert(isCompareZero(Compare) && "Expected a compare with 0.");
2219 return Compare.getOperand(i: isLoadAndTestAsCmp(MI: Compare) ? 1 : 0).getReg();
2220}
2221
2222bool SystemZInstrInfo::
2223prepareCompareSwapOperands(MachineBasicBlock::iterator const MBBI) const {
2224 assert(MBBI->isCompare() && MBBI->getOperand(0).isReg() &&
2225 MBBI->getOperand(1).isReg() && !MBBI->mayLoad() &&
2226 "Not a compare reg/reg.");
2227
2228 MachineBasicBlock *MBB = MBBI->getParent();
2229 bool CCLive = true;
2230 SmallVector<MachineInstr *, 4> CCUsers;
2231 for (MachineInstr &MI : llvm::make_range(x: std::next(x: MBBI), y: MBB->end())) {
2232 if (MI.readsRegister(Reg: SystemZ::CC, /*TRI=*/nullptr)) {
2233 unsigned Flags = MI.getDesc().TSFlags;
2234 if ((Flags & SystemZII::CCMaskFirst) || (Flags & SystemZII::CCMaskLast))
2235 CCUsers.push_back(Elt: &MI);
2236 else
2237 return false;
2238 }
2239 if (MI.definesRegister(Reg: SystemZ::CC, /*TRI=*/nullptr)) {
2240 CCLive = false;
2241 break;
2242 }
2243 }
2244 if (CCLive) {
2245 LiveRegUnits LiveRegs(*MBB->getParent()->getSubtarget().getRegisterInfo());
2246 LiveRegs.addLiveOuts(MBB: *MBB);
2247 if (!LiveRegs.available(Reg: SystemZ::CC))
2248 return false;
2249 }
2250
2251 // Update all CC users.
2252 for (unsigned Idx = 0; Idx < CCUsers.size(); ++Idx) {
2253 unsigned Flags = CCUsers[Idx]->getDesc().TSFlags;
2254 unsigned FirstOpNum = ((Flags & SystemZII::CCMaskFirst) ?
2255 0 : CCUsers[Idx]->getNumExplicitOperands() - 2);
2256 MachineOperand &CCMaskMO = CCUsers[Idx]->getOperand(i: FirstOpNum + 1);
2257 unsigned NewCCMask = SystemZ::reverseCCMask(CCMask: CCMaskMO.getImm());
2258 CCMaskMO.setImm(NewCCMask);
2259 }
2260
2261 return true;
2262}
2263
2264unsigned SystemZ::reverseCCMask(unsigned CCMask) {
2265 return ((CCMask & SystemZ::CCMASK_CMP_EQ) |
2266 ((CCMask & SystemZ::CCMASK_CMP_GT) ? SystemZ::CCMASK_CMP_LT : 0) |
2267 ((CCMask & SystemZ::CCMASK_CMP_LT) ? SystemZ::CCMASK_CMP_GT : 0) |
2268 (CCMask & SystemZ::CCMASK_CMP_UO));
2269}
2270
2271MachineBasicBlock *SystemZ::emitBlockAfter(MachineBasicBlock *MBB) {
2272 MachineFunction &MF = *MBB->getParent();
2273 MachineBasicBlock *NewMBB = MF.CreateMachineBasicBlock(BB: MBB->getBasicBlock());
2274 MF.insert(MBBI: std::next(x: MachineFunction::iterator(MBB)), MBB: NewMBB);
2275 return NewMBB;
2276}
2277
2278MachineBasicBlock *SystemZ::splitBlockAfter(MachineBasicBlock::iterator MI,
2279 MachineBasicBlock *MBB) {
2280 MachineBasicBlock *NewMBB = emitBlockAfter(MBB);
2281 NewMBB->splice(Where: NewMBB->begin(), Other: MBB,
2282 From: std::next(x: MachineBasicBlock::iterator(MI)), To: MBB->end());
2283 NewMBB->transferSuccessorsAndUpdatePHIs(FromMBB: MBB);
2284 return NewMBB;
2285}
2286
2287MachineBasicBlock *SystemZ::splitBlockBefore(MachineBasicBlock::iterator MI,
2288 MachineBasicBlock *MBB) {
2289 MachineBasicBlock *NewMBB = emitBlockAfter(MBB);
2290 NewMBB->splice(Where: NewMBB->begin(), Other: MBB, From: MI, To: MBB->end());
2291 NewMBB->transferSuccessorsAndUpdatePHIs(FromMBB: MBB);
2292 return NewMBB;
2293}
2294
2295unsigned SystemZInstrInfo::getLoadAndTrap(unsigned Opcode) const {
2296 if (!STI.hasLoadAndTrap())
2297 return 0;
2298 switch (Opcode) {
2299 case SystemZ::L:
2300 case SystemZ::LY:
2301 return SystemZ::LAT;
2302 case SystemZ::LG:
2303 return SystemZ::LGAT;
2304 case SystemZ::LFH:
2305 return SystemZ::LFHAT;
2306 case SystemZ::LLGF:
2307 return SystemZ::LLGFAT;
2308 case SystemZ::LLGT:
2309 return SystemZ::LLGTAT;
2310 }
2311 return 0;
2312}
2313
2314void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
2315 MachineBasicBlock::iterator MBBI,
2316 unsigned Reg, uint64_t Value) const {
2317 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
2318 unsigned Opcode = 0;
2319 if (isInt<16>(x: Value))
2320 Opcode = SystemZ::LGHI;
2321 else if (SystemZ::isImmLL(Val: Value))
2322 Opcode = SystemZ::LLILL;
2323 else if (SystemZ::isImmLH(Val: Value)) {
2324 Opcode = SystemZ::LLILH;
2325 Value >>= 16;
2326 }
2327 else if (isInt<32>(x: Value))
2328 Opcode = SystemZ::LGFI;
2329 if (Opcode) {
2330 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode), DestReg: Reg).addImm(Val: Value);
2331 return;
2332 }
2333
2334 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
2335 assert (MRI.isSSA() && "Huge values only handled before reg-alloc .");
2336 Register Reg0 = MRI.createVirtualRegister(RegClass: &SystemZ::GR64BitRegClass);
2337 Register Reg1 = MRI.createVirtualRegister(RegClass: &SystemZ::GR64BitRegClass);
2338 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::IMPLICIT_DEF), DestReg: Reg0);
2339 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::IIHF64), DestReg: Reg1)
2340 .addReg(RegNo: Reg0).addImm(Val: Value >> 32);
2341 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: get(Opcode: SystemZ::IILF64), DestReg: Reg)
2342 .addReg(RegNo: Reg1).addImm(Val: Value & ((uint64_t(1) << 32) - 1));
2343}
2344
2345bool SystemZInstrInfo::verifyInstruction(const MachineInstr &MI,
2346 StringRef &ErrInfo) const {
2347 const MCInstrDesc &MCID = MI.getDesc();
2348 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
2349 if (I >= MCID.getNumOperands())
2350 break;
2351 const MachineOperand &Op = MI.getOperand(i: I);
2352 const MCOperandInfo &MCOI = MCID.operands()[I];
2353 // Addressing modes have register and immediate operands. Op should be a
2354 // register (or frame index) operand if MCOI.RegClass contains a valid
2355 // register class, or an immediate otherwise.
2356 if (MCOI.OperandType == MCOI::OPERAND_MEMORY &&
2357 ((MCOI.RegClass != -1 && !Op.isReg() && !Op.isFI()) ||
2358 (MCOI.RegClass == -1 && !Op.isImm()))) {
2359 ErrInfo = "Addressing mode operands corrupt!";
2360 return false;
2361 }
2362 }
2363
2364 return true;
2365}
2366
2367bool SystemZInstrInfo::
2368areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
2369 const MachineInstr &MIb) const {
2370
2371 if (!MIa.hasOneMemOperand() || !MIb.hasOneMemOperand())
2372 return false;
2373
2374 // If mem-operands show that the same address Value is used by both
2375 // instructions, check for non-overlapping offsets and widths. Not
2376 // sure if a register based analysis would be an improvement...
2377
2378 MachineMemOperand *MMOa = *MIa.memoperands_begin();
2379 MachineMemOperand *MMOb = *MIb.memoperands_begin();
2380 const Value *VALa = MMOa->getValue();
2381 const Value *VALb = MMOb->getValue();
2382 bool SameVal = (VALa && VALb && (VALa == VALb));
2383 if (!SameVal) {
2384 const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
2385 const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
2386 if (PSVa && PSVb && (PSVa == PSVb))
2387 SameVal = true;
2388 }
2389 if (SameVal) {
2390 int OffsetA = MMOa->getOffset(), OffsetB = MMOb->getOffset();
2391 LocationSize WidthA = MMOa->getSize(), WidthB = MMOb->getSize();
2392 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2393 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2394 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2395 if (LowWidth.hasValue() &&
2396 LowOffset + (int)LowWidth.getValue() <= HighOffset)
2397 return true;
2398 }
2399
2400 return false;
2401}
2402
2403bool SystemZInstrInfo::getConstValDefinedInReg(const MachineInstr &MI,
2404 const Register Reg,
2405 int64_t &ImmVal) const {
2406
2407 if (MI.getOpcode() == SystemZ::VGBM && Reg == MI.getOperand(i: 0).getReg()) {
2408 ImmVal = MI.getOperand(i: 1).getImm();
2409 // TODO: Handle non-0 values
2410 return ImmVal == 0;
2411 }
2412
2413 return false;
2414}
2415
2416std::optional<DestSourcePair>
2417SystemZInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
2418 // if MI is a simple single-register copy operation, return operand pair
2419 if (MI.isMoveReg())
2420 return DestSourcePair(MI.getOperand(i: 0), MI.getOperand(i: 1));
2421
2422 return std::nullopt;
2423}
2424
2425std::pair<unsigned, unsigned>
2426SystemZInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
2427 return std::make_pair(x&: TF, y: 0u);
2428}
2429
2430ArrayRef<std::pair<unsigned, const char *>>
2431SystemZInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
2432 using namespace SystemZII;
2433
2434 static const std::pair<unsigned, const char *> TargetFlags[] = {
2435 {MO_GOT, "systemz-got"},
2436 {MO_INDNTPOFF, "systemz-indntpoff"},
2437 {MO_ADA_DATA_SYMBOL_ADDR, "systemz-ada-datasymboladdr"},
2438 {MO_ADA_INDIRECT_FUNC_DESC, "systemz-ada-indirectfuncdesc"},
2439 {MO_ADA_DIRECT_FUNC_DESC, "systemz-ada-directfuncdesc"}};
2440 return ArrayRef(TargetFlags);
2441}
2442
2443bool SystemZInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
2444 const MachineBasicBlock *MBB,
2445 const MachineFunction &MF) const {
2446 if (TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF))
2447 return true;
2448 return MI.getOpcode() == SystemZ::FENCE ||
2449 MI.getOpcode() == TargetOpcode::PATCHABLE_FUNCTION_ENTER;
2450}
2451
2452MCInst SystemZInstrInfo::getNop() const {
2453 return MCInstBuilder(SystemZ::NOPR).addReg(Reg: 0);
2454}
2455