LLVM 19.0.0git
SystemZInstrInfo.cpp
Go to the documentation of this file.
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"
15#include "SystemZ.h"
16#include "SystemZInstrBuilder.h"
17#include "SystemZSubtarget.h"
18#include "llvm/ADT/Statistic.h"
35#include "llvm/MC/MCInstrDesc.h"
41#include <cassert>
42#include <cstdint>
43#include <iterator>
44
45using namespace llvm;
46
47#define GET_INSTRINFO_CTOR_DTOR
48#define GET_INSTRMAP_INFO
49#include "SystemZGenInstrInfo.inc"
50
51#define DEBUG_TYPE "systemz-II"
52
53// Return a mask with Count low bits set.
54static uint64_t allOnes(unsigned int Count) {
55 return Count == 0 ? 0 : (uint64_t(1) << (Count - 1) << 1) - 1;
56}
57
58// Pin the vtable to this file.
59void SystemZInstrInfo::anchor() {}
60
62 : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKDOWN, SystemZ::ADJCALLSTACKUP),
63 RI(sti.getSpecialRegisters()->getReturnFunctionAddressRegister()),
64 STI(sti) {}
65
66// MI is a 128-bit load or store. Split it into two 64-bit loads or stores,
67// each having the opcode given by NewOpcode.
68void SystemZInstrInfo::splitMove(MachineBasicBlock::iterator MI,
69 unsigned NewOpcode) const {
70 MachineBasicBlock *MBB = MI->getParent();
72
73 // Get two load or store instructions. Use the original instruction for one
74 // of them (arbitrarily the second here) and create a clone for the other.
75 MachineInstr *EarlierMI = MF.CloneMachineInstr(&*MI);
76 MBB->insert(MI, EarlierMI);
77
78 // Set up the two 64-bit registers and remember super reg and its flags.
79 MachineOperand &HighRegOp = EarlierMI->getOperand(0);
80 MachineOperand &LowRegOp = MI->getOperand(0);
81 Register Reg128 = LowRegOp.getReg();
82 unsigned Reg128Killed = getKillRegState(LowRegOp.isKill());
83 unsigned Reg128Undef = getUndefRegState(LowRegOp.isUndef());
84 HighRegOp.setReg(RI.getSubReg(HighRegOp.getReg(), SystemZ::subreg_h64));
85 LowRegOp.setReg(RI.getSubReg(LowRegOp.getReg(), SystemZ::subreg_l64));
86
87 if (MI->mayStore()) {
88 // Add implicit uses of the super register in case one of the subregs is
89 // undefined. We could track liveness and skip storing an undefined
90 // subreg, but this is hopefully rare (discovered with llvm-stress).
91 // If Reg128 was killed, set kill flag on MI.
92 unsigned Reg128UndefImpl = (Reg128Undef | RegState::Implicit);
93 MachineInstrBuilder(MF, EarlierMI).addReg(Reg128, Reg128UndefImpl);
94 MachineInstrBuilder(MF, MI).addReg(Reg128, (Reg128UndefImpl | Reg128Killed));
95 }
96
97 // The address in the first (high) instruction is already correct.
98 // Adjust the offset in the second (low) instruction.
99 MachineOperand &HighOffsetOp = EarlierMI->getOperand(2);
100 MachineOperand &LowOffsetOp = MI->getOperand(2);
101 LowOffsetOp.setImm(LowOffsetOp.getImm() + 8);
102
103 // Clear the kill flags on the registers in the first instruction.
104 if (EarlierMI->getOperand(0).isReg() && EarlierMI->getOperand(0).isUse())
105 EarlierMI->getOperand(0).setIsKill(false);
106 EarlierMI->getOperand(1).setIsKill(false);
107 EarlierMI->getOperand(3).setIsKill(false);
108
109 // Set the opcodes.
110 unsigned HighOpcode = getOpcodeForOffset(NewOpcode, HighOffsetOp.getImm());
111 unsigned LowOpcode = getOpcodeForOffset(NewOpcode, LowOffsetOp.getImm());
112 assert(HighOpcode && LowOpcode && "Both offsets should be in range");
113
114 EarlierMI->setDesc(get(HighOpcode));
115 MI->setDesc(get(LowOpcode));
116}
117
118// Split ADJDYNALLOC instruction MI.
119void SystemZInstrInfo::splitAdjDynAlloc(MachineBasicBlock::iterator MI) const {
120 MachineBasicBlock *MBB = MI->getParent();
121 MachineFunction &MF = *MBB->getParent();
122 MachineFrameInfo &MFFrame = MF.getFrameInfo();
123 MachineOperand &OffsetMO = MI->getOperand(2);
125
126 uint64_t Offset = (MFFrame.getMaxCallFrameSize() +
127 Regs->getCallFrameSize() +
128 Regs->getStackPointerBias() +
129 OffsetMO.getImm());
130 unsigned NewOpcode = getOpcodeForOffset(SystemZ::LA, Offset);
131 assert(NewOpcode && "No support for huge argument lists yet");
132 MI->setDesc(get(NewOpcode));
133 OffsetMO.setImm(Offset);
134}
135
136// MI is an RI-style pseudo instruction. Replace it with LowOpcode
137// if the first operand is a low GR32 and HighOpcode if the first operand
138// is a high GR32. ConvertHigh is true if LowOpcode takes a signed operand
139// and HighOpcode takes an unsigned 32-bit operand. In those cases,
140// MI has the same kind of operand as LowOpcode, so needs to be converted
141// if HighOpcode is used.
142void SystemZInstrInfo::expandRIPseudo(MachineInstr &MI, unsigned LowOpcode,
143 unsigned HighOpcode,
144 bool ConvertHigh) const {
145 Register Reg = MI.getOperand(0).getReg();
146 bool IsHigh = SystemZ::isHighReg(Reg);
147 MI.setDesc(get(IsHigh ? HighOpcode : LowOpcode));
148 if (IsHigh && ConvertHigh)
149 MI.getOperand(1).setImm(uint32_t(MI.getOperand(1).getImm()));
150}
151
152// MI is a three-operand RIE-style pseudo instruction. Replace it with
153// LowOpcodeK if the registers are both low GR32s, otherwise use a move
154// followed by HighOpcode or LowOpcode, depending on whether the target
155// is a high or low GR32.
156void SystemZInstrInfo::expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
157 unsigned LowOpcodeK,
158 unsigned HighOpcode) const {
159 Register DestReg = MI.getOperand(0).getReg();
160 Register SrcReg = MI.getOperand(1).getReg();
161 bool DestIsHigh = SystemZ::isHighReg(DestReg);
162 bool SrcIsHigh = SystemZ::isHighReg(SrcReg);
163 if (!DestIsHigh && !SrcIsHigh)
164 MI.setDesc(get(LowOpcodeK));
165 else {
166 if (DestReg != SrcReg) {
167 emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(), DestReg, SrcReg,
168 SystemZ::LR, 32, MI.getOperand(1).isKill(),
169 MI.getOperand(1).isUndef());
170 MI.getOperand(1).setReg(DestReg);
171 }
172 MI.setDesc(get(DestIsHigh ? HighOpcode : LowOpcode));
173 MI.tieOperands(0, 1);
174 }
175}
176
177// MI is an RXY-style pseudo instruction. Replace it with LowOpcode
178// if the first operand is a low GR32 and HighOpcode if the first operand
179// is a high GR32.
180void SystemZInstrInfo::expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode,
181 unsigned HighOpcode) const {
182 Register Reg = MI.getOperand(0).getReg();
183 unsigned Opcode = getOpcodeForOffset(
184 SystemZ::isHighReg(Reg) ? HighOpcode : LowOpcode,
185 MI.getOperand(2).getImm());
186 MI.setDesc(get(Opcode));
187}
188
189// MI is a load-on-condition pseudo instruction with a single register
190// (source or destination) operand. Replace it with LowOpcode if the
191// register is a low GR32 and HighOpcode if the register is a high GR32.
192void SystemZInstrInfo::expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode,
193 unsigned HighOpcode) const {
194 Register Reg = MI.getOperand(0).getReg();
195 unsigned Opcode = SystemZ::isHighReg(Reg) ? HighOpcode : LowOpcode;
196 MI.setDesc(get(Opcode));
197}
198
199// MI is an RR-style pseudo instruction that zero-extends the low Size bits
200// of one GRX32 into another. Replace it with LowOpcode if both operands
201// are low registers, otherwise use RISB[LH]G.
202void SystemZInstrInfo::expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
203 unsigned Size) const {
205 emitGRX32Move(*MI.getParent(), MI, MI.getDebugLoc(),
206 MI.getOperand(0).getReg(), MI.getOperand(1).getReg(), LowOpcode,
207 Size, MI.getOperand(1).isKill(), MI.getOperand(1).isUndef());
208
209 // Keep the remaining operands as-is.
210 for (const MachineOperand &MO : llvm::drop_begin(MI.operands(), 2))
211 MIB.add(MO);
212
213 MI.eraseFromParent();
214}
215
216void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const {
217 MachineBasicBlock *MBB = MI->getParent();
218 MachineFunction &MF = *MBB->getParent();
219 const Register Reg64 = MI->getOperand(0).getReg();
220 const Register Reg32 = RI.getSubReg(Reg64, SystemZ::subreg_l32);
221
222 // EAR can only load the low subregister so us a shift for %a0 to produce
223 // the GR containing %a0 and %a1.
224
225 // ear <reg>, %a0
226 BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::EAR), Reg32)
227 .addReg(SystemZ::A0)
229
230 // sllg <reg>, <reg>, 32
231 BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::SLLG), Reg64)
232 .addReg(Reg64)
233 .addReg(0)
234 .addImm(32);
235
236 // ear <reg>, %a1
237 BuildMI(*MBB, MI, MI->getDebugLoc(), get(SystemZ::EAR), Reg32)
238 .addReg(SystemZ::A1);
239
240 // lg <reg>, 40(<reg>)
241 MI->setDesc(get(SystemZ::LG));
242 MachineInstrBuilder(MF, MI).addReg(Reg64).addImm(40).addReg(0);
243}
244
245// Emit a zero-extending move from 32-bit GPR SrcReg to 32-bit GPR
246// DestReg before MBBI in MBB. Use LowLowOpcode when both DestReg and SrcReg
247// are low registers, otherwise use RISB[LH]G. Size is the number of bits
248// taken from the low end of SrcReg (8 for LLCR, 16 for LLHR and 32 for LR).
249// KillSrc is true if this move is the last use of SrcReg.
251SystemZInstrInfo::emitGRX32Move(MachineBasicBlock &MBB,
253 const DebugLoc &DL, unsigned DestReg,
254 unsigned SrcReg, unsigned LowLowOpcode,
255 unsigned Size, bool KillSrc,
256 bool UndefSrc) const {
257 unsigned Opcode;
258 bool DestIsHigh = SystemZ::isHighReg(DestReg);
259 bool SrcIsHigh = SystemZ::isHighReg(SrcReg);
260 if (DestIsHigh && SrcIsHigh)
261 Opcode = SystemZ::RISBHH;
262 else if (DestIsHigh && !SrcIsHigh)
263 Opcode = SystemZ::RISBHL;
264 else if (!DestIsHigh && SrcIsHigh)
265 Opcode = SystemZ::RISBLH;
266 else {
267 return BuildMI(MBB, MBBI, DL, get(LowLowOpcode), DestReg)
268 .addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc));
269 }
270 unsigned Rotate = (DestIsHigh != SrcIsHigh ? 32 : 0);
271 return BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
272 .addReg(DestReg, RegState::Undef)
273 .addReg(SrcReg, getKillRegState(KillSrc) | getUndefRegState(UndefSrc))
274 .addImm(32 - Size).addImm(128 + 31).addImm(Rotate);
275}
276
278 bool NewMI,
279 unsigned OpIdx1,
280 unsigned OpIdx2) const {
281 auto cloneIfNew = [NewMI](MachineInstr &MI) -> MachineInstr & {
282 if (NewMI)
283 return *MI.getParent()->getParent()->CloneMachineInstr(&MI);
284 return MI;
285 };
286
287 switch (MI.getOpcode()) {
288 case SystemZ::SELRMux:
289 case SystemZ::SELFHR:
290 case SystemZ::SELR:
291 case SystemZ::SELGR:
292 case SystemZ::LOCRMux:
293 case SystemZ::LOCFHR:
294 case SystemZ::LOCR:
295 case SystemZ::LOCGR: {
296 auto &WorkingMI = cloneIfNew(MI);
297 // Invert condition.
298 unsigned CCValid = WorkingMI.getOperand(3).getImm();
299 unsigned CCMask = WorkingMI.getOperand(4).getImm();
300 WorkingMI.getOperand(4).setImm(CCMask ^ CCValid);
301 return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false,
302 OpIdx1, OpIdx2);
303 }
304 default:
305 return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
306 }
307}
308
309// If MI is a simple load or store for a frame object, return the register
310// it loads or stores and set FrameIndex to the index of the frame object.
311// Return 0 otherwise.
312//
313// Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores.
314static int isSimpleMove(const MachineInstr &MI, int &FrameIndex,
315 unsigned Flag) {
316 const MCInstrDesc &MCID = MI.getDesc();
317 if ((MCID.TSFlags & Flag) && MI.getOperand(1).isFI() &&
318 MI.getOperand(2).getImm() == 0 && MI.getOperand(3).getReg() == 0) {
319 FrameIndex = MI.getOperand(1).getIndex();
320 return MI.getOperand(0).getReg();
321 }
322 return 0;
323}
324
326 int &FrameIndex) const {
327 return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXLoad);
328}
329
331 int &FrameIndex) const {
332 return isSimpleMove(MI, FrameIndex, SystemZII::SimpleBDXStore);
333}
334
336 int &DestFrameIndex,
337 int &SrcFrameIndex) const {
338 // Check for MVC 0(Length,FI1),0(FI2)
339 const MachineFrameInfo &MFI = MI.getParent()->getParent()->getFrameInfo();
340 if (MI.getOpcode() != SystemZ::MVC || !MI.getOperand(0).isFI() ||
341 MI.getOperand(1).getImm() != 0 || !MI.getOperand(3).isFI() ||
342 MI.getOperand(4).getImm() != 0)
343 return false;
344
345 // Check that Length covers the full slots.
346 int64_t Length = MI.getOperand(2).getImm();
347 unsigned FI1 = MI.getOperand(0).getIndex();
348 unsigned FI2 = MI.getOperand(3).getIndex();
349 if (MFI.getObjectSize(FI1) != Length ||
350 MFI.getObjectSize(FI2) != Length)
351 return false;
352
353 DestFrameIndex = FI1;
354 SrcFrameIndex = FI2;
355 return true;
356}
357
360 MachineBasicBlock *&FBB,
362 bool AllowModify) const {
363 // Most of the code and comments here are boilerplate.
364
365 // Start from the bottom of the block and work up, examining the
366 // terminator instructions.
368 while (I != MBB.begin()) {
369 --I;
370 if (I->isDebugInstr())
371 continue;
372
373 // Working from the bottom, when we see a non-terminator instruction, we're
374 // done.
375 if (!isUnpredicatedTerminator(*I))
376 break;
377
378 // A terminator that isn't a branch can't easily be handled by this
379 // analysis.
380 if (!I->isBranch())
381 return true;
382
383 // Can't handle indirect branches.
385 if (!Branch.hasMBBTarget())
386 return true;
387
388 // Punt on compound branches.
389 if (Branch.Type != SystemZII::BranchNormal)
390 return true;
391
392 if (Branch.CCMask == SystemZ::CCMASK_ANY) {
393 // Handle unconditional branches.
394 if (!AllowModify) {
395 TBB = Branch.getMBBTarget();
396 continue;
397 }
398
399 // If the block has any instructions after a JMP, delete them.
400 MBB.erase(std::next(I), MBB.end());
401
402 Cond.clear();
403 FBB = nullptr;
404
405 // Delete the JMP if it's equivalent to a fall-through.
406 if (MBB.isLayoutSuccessor(Branch.getMBBTarget())) {
407 TBB = nullptr;
408 I->eraseFromParent();
409 I = MBB.end();
410 continue;
411 }
412
413 // TBB is used to indicate the unconditinal destination.
414 TBB = Branch.getMBBTarget();
415 continue;
416 }
417
418 // Working from the bottom, handle the first conditional branch.
419 if (Cond.empty()) {
420 // FIXME: add X86-style branch swap
421 FBB = TBB;
422 TBB = Branch.getMBBTarget();
423 Cond.push_back(MachineOperand::CreateImm(Branch.CCValid));
424 Cond.push_back(MachineOperand::CreateImm(Branch.CCMask));
425 continue;
426 }
427
428 // Handle subsequent conditional branches.
429 assert(Cond.size() == 2 && TBB && "Should have seen a conditional branch");
430
431 // Only handle the case where all conditional branches branch to the same
432 // destination.
433 if (TBB != Branch.getMBBTarget())
434 return true;
435
436 // If the conditions are the same, we can leave them alone.
437 unsigned OldCCValid = Cond[0].getImm();
438 unsigned OldCCMask = Cond[1].getImm();
439 if (OldCCValid == Branch.CCValid && OldCCMask == Branch.CCMask)
440 continue;
441
442 // FIXME: Try combining conditions like X86 does. Should be easy on Z!
443 return false;
444 }
445
446 return false;
447}
448
450 int *BytesRemoved) const {
451 assert(!BytesRemoved && "code size not handled");
452
453 // Most of the code and comments here are boilerplate.
455 unsigned Count = 0;
456
457 while (I != MBB.begin()) {
458 --I;
459 if (I->isDebugInstr())
460 continue;
461 if (!I->isBranch())
462 break;
463 if (!getBranchInfo(*I).hasMBBTarget())
464 break;
465 // Remove the branch.
466 I->eraseFromParent();
467 I = MBB.end();
468 ++Count;
469 }
470
471 return Count;
472}
473
476 assert(Cond.size() == 2 && "Invalid condition");
477 Cond[1].setImm(Cond[1].getImm() ^ Cond[0].getImm());
478 return false;
479}
480
485 const DebugLoc &DL,
486 int *BytesAdded) const {
487 // In this function we output 32-bit branches, which should always
488 // have enough range. They can be shortened and relaxed by later code
489 // in the pipeline, if desired.
490
491 // Shouldn't be a fall through.
492 assert(TBB && "insertBranch must not be told to insert a fallthrough");
493 assert((Cond.size() == 2 || Cond.size() == 0) &&
494 "SystemZ branch conditions have one component!");
495 assert(!BytesAdded && "code size not handled");
496
497 if (Cond.empty()) {
498 // Unconditional branch?
499 assert(!FBB && "Unconditional branch with multiple successors!");
500 BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(TBB);
501 return 1;
502 }
503
504 // Conditional branch.
505 unsigned Count = 0;
506 unsigned CCValid = Cond[0].getImm();
507 unsigned CCMask = Cond[1].getImm();
508 BuildMI(&MBB, DL, get(SystemZ::BRC))
509 .addImm(CCValid).addImm(CCMask).addMBB(TBB);
510 ++Count;
511
512 if (FBB) {
513 // Two-way Conditional branch. Insert the second branch.
514 BuildMI(&MBB, DL, get(SystemZ::J)).addMBB(FBB);
515 ++Count;
516 }
517 return Count;
518}
519
521 Register &SrcReg2, int64_t &Mask,
522 int64_t &Value) const {
523 assert(MI.isCompare() && "Caller should have checked for a comparison");
524
525 if (MI.getNumExplicitOperands() == 2 && MI.getOperand(0).isReg() &&
526 MI.getOperand(1).isImm()) {
527 SrcReg = MI.getOperand(0).getReg();
528 SrcReg2 = 0;
529 Value = MI.getOperand(1).getImm();
530 Mask = ~0;
531 return true;
532 }
533
534 return false;
535}
536
539 Register DstReg, Register TrueReg,
540 Register FalseReg, int &CondCycles,
541 int &TrueCycles,
542 int &FalseCycles) const {
543 // Not all subtargets have LOCR instructions.
544 if (!STI.hasLoadStoreOnCond())
545 return false;
546 if (Pred.size() != 2)
547 return false;
548
549 // Check register classes.
551 const TargetRegisterClass *RC =
552 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
553 if (!RC)
554 return false;
555
556 // We have LOCR instructions for 32 and 64 bit general purpose registers.
557 if ((STI.hasLoadStoreOnCond2() &&
558 SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) ||
559 SystemZ::GR32BitRegClass.hasSubClassEq(RC) ||
560 SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
561 CondCycles = 2;
562 TrueCycles = 2;
563 FalseCycles = 2;
564 return true;
565 }
566
567 // Can't do anything else.
568 return false;
569}
570
573 const DebugLoc &DL, Register DstReg,
575 Register TrueReg,
576 Register FalseReg) const {
578 const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
579
580 assert(Pred.size() == 2 && "Invalid condition");
581 unsigned CCValid = Pred[0].getImm();
582 unsigned CCMask = Pred[1].getImm();
583
584 unsigned Opc;
585 if (SystemZ::GRX32BitRegClass.hasSubClassEq(RC)) {
586 if (STI.hasMiscellaneousExtensions3())
587 Opc = SystemZ::SELRMux;
588 else if (STI.hasLoadStoreOnCond2())
589 Opc = SystemZ::LOCRMux;
590 else {
591 Opc = SystemZ::LOCR;
592 MRI.constrainRegClass(DstReg, &SystemZ::GR32BitRegClass);
593 Register TReg = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
594 Register FReg = MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
595 BuildMI(MBB, I, DL, get(TargetOpcode::COPY), TReg).addReg(TrueReg);
596 BuildMI(MBB, I, DL, get(TargetOpcode::COPY), FReg).addReg(FalseReg);
597 TrueReg = TReg;
598 FalseReg = FReg;
599 }
600 } else if (SystemZ::GR64BitRegClass.hasSubClassEq(RC)) {
601 if (STI.hasMiscellaneousExtensions3())
602 Opc = SystemZ::SELGR;
603 else
604 Opc = SystemZ::LOCGR;
605 } else
606 llvm_unreachable("Invalid register class");
607
608 BuildMI(MBB, I, DL, get(Opc), DstReg)
609 .addReg(FalseReg).addReg(TrueReg)
610 .addImm(CCValid).addImm(CCMask);
611}
612
614 Register Reg,
615 MachineRegisterInfo *MRI) const {
616 unsigned DefOpc = DefMI.getOpcode();
617 if (DefOpc != SystemZ::LHIMux && DefOpc != SystemZ::LHI &&
618 DefOpc != SystemZ::LGHI)
619 return false;
620 if (DefMI.getOperand(0).getReg() != Reg)
621 return false;
622 int32_t ImmVal = (int32_t)DefMI.getOperand(1).getImm();
623
624 unsigned UseOpc = UseMI.getOpcode();
625 unsigned NewUseOpc;
626 unsigned UseIdx;
627 int CommuteIdx = -1;
628 bool TieOps = false;
629 switch (UseOpc) {
630 case SystemZ::SELRMux:
631 TieOps = true;
632 [[fallthrough]];
633 case SystemZ::LOCRMux:
634 if (!STI.hasLoadStoreOnCond2())
635 return false;
636 NewUseOpc = SystemZ::LOCHIMux;
637 if (UseMI.getOperand(2).getReg() == Reg)
638 UseIdx = 2;
639 else if (UseMI.getOperand(1).getReg() == Reg)
640 UseIdx = 2, CommuteIdx = 1;
641 else
642 return false;
643 break;
644 case SystemZ::SELGR:
645 TieOps = true;
646 [[fallthrough]];
647 case SystemZ::LOCGR:
648 if (!STI.hasLoadStoreOnCond2())
649 return false;
650 NewUseOpc = SystemZ::LOCGHI;
651 if (UseMI.getOperand(2).getReg() == Reg)
652 UseIdx = 2;
653 else if (UseMI.getOperand(1).getReg() == Reg)
654 UseIdx = 2, CommuteIdx = 1;
655 else
656 return false;
657 break;
658 default:
659 return false;
660 }
661
662 if (CommuteIdx != -1)
663 if (!commuteInstruction(UseMI, false, CommuteIdx, UseIdx))
664 return false;
665
666 bool DeleteDef = MRI->hasOneNonDBGUse(Reg);
667 UseMI.setDesc(get(NewUseOpc));
668 if (TieOps)
669 UseMI.tieOperands(0, 1);
670 UseMI.getOperand(UseIdx).ChangeToImmediate(ImmVal);
671 if (DeleteDef)
672 DefMI.eraseFromParent();
673
674 return true;
675}
676
678 unsigned Opcode = MI.getOpcode();
679 if (Opcode == SystemZ::Return ||
680 Opcode == SystemZ::Return_XPLINK ||
681 Opcode == SystemZ::Trap ||
682 Opcode == SystemZ::CallJG ||
683 Opcode == SystemZ::CallBR)
684 return true;
685 return false;
686}
687
690 unsigned NumCycles, unsigned ExtraPredCycles,
691 BranchProbability Probability) const {
692 // Avoid using conditional returns at the end of a loop (since then
693 // we'd need to emit an unconditional branch to the beginning anyway,
694 // making the loop body longer). This doesn't apply for low-probability
695 // loops (eg. compare-and-swap retry), so just decide based on branch
696 // probability instead of looping structure.
697 // However, since Compare and Trap instructions cost the same as a regular
698 // Compare instruction, we should allow the if conversion to convert this
699 // into a Conditional Compare regardless of the branch probability.
700 if (MBB.getLastNonDebugInstr()->getOpcode() != SystemZ::Trap &&
701 MBB.succ_empty() && Probability < BranchProbability(1, 8))
702 return false;
703 // For now only convert single instructions.
704 return NumCycles == 1;
705}
706
709 unsigned NumCyclesT, unsigned ExtraPredCyclesT,
710 MachineBasicBlock &FMBB,
711 unsigned NumCyclesF, unsigned ExtraPredCyclesF,
712 BranchProbability Probability) const {
713 // For now avoid converting mutually-exclusive cases.
714 return false;
715}
716
719 BranchProbability Probability) const {
720 // For now only duplicate single instructions.
721 return NumCycles == 1;
722}
723
726 assert(Pred.size() == 2 && "Invalid condition");
727 unsigned CCValid = Pred[0].getImm();
728 unsigned CCMask = Pred[1].getImm();
729 assert(CCMask > 0 && CCMask < 15 && "Invalid predicate");
730 unsigned Opcode = MI.getOpcode();
731 if (Opcode == SystemZ::Trap) {
732 MI.setDesc(get(SystemZ::CondTrap));
733 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
734 .addImm(CCValid).addImm(CCMask)
735 .addReg(SystemZ::CC, RegState::Implicit);
736 return true;
737 }
738 if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) {
739 MI.setDesc(get(Opcode == SystemZ::Return ? SystemZ::CondReturn
740 : SystemZ::CondReturn_XPLINK));
741 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
742 .addImm(CCValid)
743 .addImm(CCMask)
744 .addReg(SystemZ::CC, RegState::Implicit);
745 return true;
746 }
747 if (Opcode == SystemZ::CallJG) {
748 MachineOperand FirstOp = MI.getOperand(0);
749 const uint32_t *RegMask = MI.getOperand(1).getRegMask();
750 MI.removeOperand(1);
751 MI.removeOperand(0);
752 MI.setDesc(get(SystemZ::CallBRCL));
753 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
754 .addImm(CCValid)
755 .addImm(CCMask)
756 .add(FirstOp)
757 .addRegMask(RegMask)
758 .addReg(SystemZ::CC, RegState::Implicit);
759 return true;
760 }
761 if (Opcode == SystemZ::CallBR) {
762 MachineOperand Target = MI.getOperand(0);
763 const uint32_t *RegMask = MI.getOperand(1).getRegMask();
764 MI.removeOperand(1);
765 MI.removeOperand(0);
766 MI.setDesc(get(SystemZ::CallBCR));
767 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
768 .addImm(CCValid).addImm(CCMask)
769 .add(Target)
770 .addRegMask(RegMask)
771 .addReg(SystemZ::CC, RegState::Implicit);
772 return true;
773 }
774 return false;
775}
776
779 const DebugLoc &DL, MCRegister DestReg,
780 MCRegister SrcReg, bool KillSrc) const {
781 // Split 128-bit GPR moves into two 64-bit moves. Add implicit uses of the
782 // super register in case one of the subregs is undefined.
783 // This handles ADDR128 too.
784 if (SystemZ::GR128BitRegClass.contains(DestReg, SrcReg)) {
785 copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_h64),
786 RI.getSubReg(SrcReg, SystemZ::subreg_h64), KillSrc);
787 MachineInstrBuilder(*MBB.getParent(), std::prev(MBBI))
788 .addReg(SrcReg, RegState::Implicit);
789 copyPhysReg(MBB, MBBI, DL, RI.getSubReg(DestReg, SystemZ::subreg_l64),
790 RI.getSubReg(SrcReg, SystemZ::subreg_l64), KillSrc);
791 MachineInstrBuilder(*MBB.getParent(), std::prev(MBBI))
792 .addReg(SrcReg, (getKillRegState(KillSrc) | RegState::Implicit));
793 return;
794 }
795
796 if (SystemZ::GRX32BitRegClass.contains(DestReg, SrcReg)) {
797 emitGRX32Move(MBB, MBBI, DL, DestReg, SrcReg, SystemZ::LR, 32, KillSrc,
798 false);
799 return;
800 }
801
802 // Move 128-bit floating-point values between VR128 and FP128.
803 if (SystemZ::VR128BitRegClass.contains(DestReg) &&
804 SystemZ::FP128BitRegClass.contains(SrcReg)) {
805 MCRegister SrcRegHi =
806 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64),
807 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
808 MCRegister SrcRegLo =
809 RI.getMatchingSuperReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64),
810 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
811
812 BuildMI(MBB, MBBI, DL, get(SystemZ::VMRHG), DestReg)
813 .addReg(SrcRegHi, getKillRegState(KillSrc))
814 .addReg(SrcRegLo, getKillRegState(KillSrc));
815 return;
816 }
817 if (SystemZ::FP128BitRegClass.contains(DestReg) &&
818 SystemZ::VR128BitRegClass.contains(SrcReg)) {
819 MCRegister DestRegHi =
820 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_h64),
821 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
822 MCRegister DestRegLo =
823 RI.getMatchingSuperReg(RI.getSubReg(DestReg, SystemZ::subreg_l64),
824 SystemZ::subreg_h64, &SystemZ::VR128BitRegClass);
825
826 if (DestRegHi != SrcReg)
827 copyPhysReg(MBB, MBBI, DL, DestRegHi, SrcReg, false);
828 BuildMI(MBB, MBBI, DL, get(SystemZ::VREPG), DestRegLo)
829 .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1);
830 return;
831 }
832
833 // Move CC value from a GR32.
834 if (DestReg == SystemZ::CC) {
835 unsigned Opcode =
836 SystemZ::GR32BitRegClass.contains(SrcReg) ? SystemZ::TMLH : SystemZ::TMHH;
837 BuildMI(MBB, MBBI, DL, get(Opcode))
838 .addReg(SrcReg, getKillRegState(KillSrc))
839 .addImm(3 << (SystemZ::IPM_CC - 16));
840 return;
841 }
842
843 // Everything else needs only one instruction.
844 unsigned Opcode;
845 if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg))
846 Opcode = SystemZ::LGR;
847 else if (SystemZ::FP32BitRegClass.contains(DestReg, SrcReg))
848 // For z13 we prefer LDR over LER to avoid partial register dependencies.
849 Opcode = STI.hasVector() ? SystemZ::LDR32 : SystemZ::LER;
850 else if (SystemZ::FP64BitRegClass.contains(DestReg, SrcReg))
851 Opcode = SystemZ::LDR;
852 else if (SystemZ::FP128BitRegClass.contains(DestReg, SrcReg))
853 Opcode = SystemZ::LXR;
854 else if (SystemZ::VR32BitRegClass.contains(DestReg, SrcReg))
855 Opcode = SystemZ::VLR32;
856 else if (SystemZ::VR64BitRegClass.contains(DestReg, SrcReg))
857 Opcode = SystemZ::VLR64;
858 else if (SystemZ::VR128BitRegClass.contains(DestReg, SrcReg))
859 Opcode = SystemZ::VLR;
860 else if (SystemZ::AR32BitRegClass.contains(DestReg, SrcReg))
861 Opcode = SystemZ::CPYA;
862 else
863 llvm_unreachable("Impossible reg-to-reg copy");
864
865 BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
866 .addReg(SrcReg, getKillRegState(KillSrc));
867}
868
871 bool isKill, int FrameIdx, const TargetRegisterClass *RC,
872 const TargetRegisterInfo *TRI, Register VReg) const {
873 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
874
875 // Callers may expect a single instruction, so keep 128-bit moves
876 // together for now and lower them after register allocation.
877 unsigned LoadOpcode, StoreOpcode;
878 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode);
879 addFrameReference(BuildMI(MBB, MBBI, DL, get(StoreOpcode))
880 .addReg(SrcReg, getKillRegState(isKill)),
881 FrameIdx);
882}
883
886 Register DestReg, int FrameIdx,
887 const TargetRegisterClass *RC,
888 const TargetRegisterInfo *TRI,
889 Register VReg) const {
890 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
891
892 // Callers may expect a single instruction, so keep 128-bit moves
893 // together for now and lower them after register allocation.
894 unsigned LoadOpcode, StoreOpcode;
895 getLoadStoreOpcodes(RC, LoadOpcode, StoreOpcode);
896 addFrameReference(BuildMI(MBB, MBBI, DL, get(LoadOpcode), DestReg),
897 FrameIdx);
898}
899
900// Return true if MI is a simple load or store with a 12-bit displacement
901// and no index. Flag is SimpleBDXLoad for loads and SimpleBDXStore for stores.
902static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) {
903 const MCInstrDesc &MCID = MI->getDesc();
904 return ((MCID.TSFlags & Flag) &&
905 isUInt<12>(MI->getOperand(2).getImm()) &&
906 MI->getOperand(3).getReg() == 0);
907}
908
909namespace {
910
911struct LogicOp {
912 LogicOp() = default;
913 LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize)
914 : RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
915
916 explicit operator bool() const { return RegSize; }
917
918 unsigned RegSize = 0;
919 unsigned ImmLSB = 0;
920 unsigned ImmSize = 0;
921};
922
923} // end anonymous namespace
924
925static LogicOp interpretAndImmediate(unsigned Opcode) {
926 switch (Opcode) {
927 case SystemZ::NILMux: return LogicOp(32, 0, 16);
928 case SystemZ::NIHMux: return LogicOp(32, 16, 16);
929 case SystemZ::NILL64: return LogicOp(64, 0, 16);
930 case SystemZ::NILH64: return LogicOp(64, 16, 16);
931 case SystemZ::NIHL64: return LogicOp(64, 32, 16);
932 case SystemZ::NIHH64: return LogicOp(64, 48, 16);
933 case SystemZ::NIFMux: return LogicOp(32, 0, 32);
934 case SystemZ::NILF64: return LogicOp(64, 0, 32);
935 case SystemZ::NIHF64: return LogicOp(64, 32, 32);
936 default: return LogicOp();
937 }
938}
939
940static void transferDeadCC(MachineInstr *OldMI, MachineInstr *NewMI) {
941 if (OldMI->registerDefIsDead(SystemZ::CC)) {
942 MachineOperand *CCDef = NewMI->findRegisterDefOperand(SystemZ::CC);
943 if (CCDef != nullptr)
944 CCDef->setIsDead(true);
945 }
946}
947
948static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI,
950 if (OldMI->getFlag(Flag))
951 NewMI->setFlag(Flag);
952}
953
956 LiveIntervals *LIS) const {
957 MachineBasicBlock *MBB = MI.getParent();
958
959 // Try to convert an AND into an RISBG-type instruction.
960 // TODO: It might be beneficial to select RISBG and shorten to AND instead.
961 if (LogicOp And = interpretAndImmediate(MI.getOpcode())) {
962 uint64_t Imm = MI.getOperand(2).getImm() << And.ImmLSB;
963 // AND IMMEDIATE leaves the other bits of the register unchanged.
964 Imm |= allOnes(And.RegSize) & ~(allOnes(And.ImmSize) << And.ImmLSB);
965 unsigned Start, End;
966 if (isRxSBGMask(Imm, And.RegSize, Start, End)) {
967 unsigned NewOpcode;
968 if (And.RegSize == 64) {
969 NewOpcode = SystemZ::RISBG;
970 // Prefer RISBGN if available, since it does not clobber CC.
971 if (STI.hasMiscellaneousExtensions())
972 NewOpcode = SystemZ::RISBGN;
973 } else {
974 NewOpcode = SystemZ::RISBMux;
975 Start &= 31;
976 End &= 31;
977 }
978 MachineOperand &Dest = MI.getOperand(0);
979 MachineOperand &Src = MI.getOperand(1);
981 BuildMI(*MBB, MI, MI.getDebugLoc(), get(NewOpcode))
982 .add(Dest)
983 .addReg(0)
984 .addReg(Src.getReg(), getKillRegState(Src.isKill()),
985 Src.getSubReg())
986 .addImm(Start)
987 .addImm(End + 128)
988 .addImm(0);
989 if (LV) {
990 unsigned NumOps = MI.getNumOperands();
991 for (unsigned I = 1; I < NumOps; ++I) {
992 MachineOperand &Op = MI.getOperand(I);
993 if (Op.isReg() && Op.isKill())
994 LV->replaceKillInstruction(Op.getReg(), MI, *MIB);
995 }
996 }
997 if (LIS)
998 LIS->ReplaceMachineInstrInMaps(MI, *MIB);
999 transferDeadCC(&MI, MIB);
1000 return MIB;
1001 }
1002 }
1003 return nullptr;
1004}
1005
1008 MachineBasicBlock::iterator InsertPt, int FrameIndex,
1009 LiveIntervals *LIS, VirtRegMap *VRM) const {
1012 const MachineFrameInfo &MFI = MF.getFrameInfo();
1013 unsigned Size = MFI.getObjectSize(FrameIndex);
1014 unsigned Opcode = MI.getOpcode();
1015
1016 // Check CC liveness if new instruction introduces a dead def of CC.
1017 SlotIndex MISlot = SlotIndex();
1018 LiveRange *CCLiveRange = nullptr;
1019 bool CCLiveAtMI = true;
1020 if (LIS) {
1021 MISlot = LIS->getSlotIndexes()->getInstructionIndex(MI).getRegSlot();
1022 auto CCUnits = TRI->regunits(MCRegister::from(SystemZ::CC));
1023 assert(range_size(CCUnits) == 1 && "CC only has one reg unit.");
1024 CCLiveRange = &LIS->getRegUnit(*CCUnits.begin());
1025 CCLiveAtMI = CCLiveRange->liveAt(MISlot);
1026 }
1027
1028 if (Ops.size() == 2 && Ops[0] == 0 && Ops[1] == 1) {
1029 if (!CCLiveAtMI && (Opcode == SystemZ::LA || Opcode == SystemZ::LAY) &&
1030 isInt<8>(MI.getOperand(2).getImm()) && !MI.getOperand(3).getReg()) {
1031 // LA(Y) %reg, CONST(%reg) -> AGSI %mem, CONST
1032 MachineInstr *BuiltMI = BuildMI(*InsertPt->getParent(), InsertPt,
1033 MI.getDebugLoc(), get(SystemZ::AGSI))
1034 .addFrameIndex(FrameIndex)
1035 .addImm(0)
1036 .addImm(MI.getOperand(2).getImm());
1037 BuiltMI->findRegisterDefOperand(SystemZ::CC)->setIsDead(true);
1038 CCLiveRange->createDeadDef(MISlot, LIS->getVNInfoAllocator());
1039 return BuiltMI;
1040 }
1041 return nullptr;
1042 }
1043
1044 // All other cases require a single operand.
1045 if (Ops.size() != 1)
1046 return nullptr;
1047
1048 unsigned OpNum = Ops[0];
1049 assert(Size * 8 ==
1050 TRI->getRegSizeInBits(*MF.getRegInfo()
1051 .getRegClass(MI.getOperand(OpNum).getReg())) &&
1052 "Invalid size combination");
1053
1054 if ((Opcode == SystemZ::AHI || Opcode == SystemZ::AGHI) && OpNum == 0 &&
1055 isInt<8>(MI.getOperand(2).getImm())) {
1056 // A(G)HI %reg, CONST -> A(G)SI %mem, CONST
1057 Opcode = (Opcode == SystemZ::AHI ? SystemZ::ASI : SystemZ::AGSI);
1058 MachineInstr *BuiltMI =
1059 BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), get(Opcode))
1060 .addFrameIndex(FrameIndex)
1061 .addImm(0)
1062 .addImm(MI.getOperand(2).getImm());
1063 transferDeadCC(&MI, BuiltMI);
1065 return BuiltMI;
1066 }
1067
1068 if ((Opcode == SystemZ::ALFI && OpNum == 0 &&
1069 isInt<8>((int32_t)MI.getOperand(2).getImm())) ||
1070 (Opcode == SystemZ::ALGFI && OpNum == 0 &&
1071 isInt<8>((int64_t)MI.getOperand(2).getImm()))) {
1072 // AL(G)FI %reg, CONST -> AL(G)SI %mem, CONST
1073 Opcode = (Opcode == SystemZ::ALFI ? SystemZ::ALSI : SystemZ::ALGSI);
1074 MachineInstr *BuiltMI =
1075 BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), get(Opcode))
1076 .addFrameIndex(FrameIndex)
1077 .addImm(0)
1078 .addImm((int8_t)MI.getOperand(2).getImm());
1079 transferDeadCC(&MI, BuiltMI);
1080 return BuiltMI;
1081 }
1082
1083 if ((Opcode == SystemZ::SLFI && OpNum == 0 &&
1084 isInt<8>((int32_t)-MI.getOperand(2).getImm())) ||
1085 (Opcode == SystemZ::SLGFI && OpNum == 0 &&
1086 isInt<8>((int64_t)-MI.getOperand(2).getImm()))) {
1087 // SL(G)FI %reg, CONST -> AL(G)SI %mem, -CONST
1088 Opcode = (Opcode == SystemZ::SLFI ? SystemZ::ALSI : SystemZ::ALGSI);
1089 MachineInstr *BuiltMI =
1090 BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(), get(Opcode))
1091 .addFrameIndex(FrameIndex)
1092 .addImm(0)
1093 .addImm((int8_t)-MI.getOperand(2).getImm());
1094 transferDeadCC(&MI, BuiltMI);
1095 return BuiltMI;
1096 }
1097
1098 unsigned MemImmOpc = 0;
1099 switch (Opcode) {
1100 case SystemZ::LHIMux:
1101 case SystemZ::LHI: MemImmOpc = SystemZ::MVHI; break;
1102 case SystemZ::LGHI: MemImmOpc = SystemZ::MVGHI; break;
1103 case SystemZ::CHIMux:
1104 case SystemZ::CHI: MemImmOpc = SystemZ::CHSI; break;
1105 case SystemZ::CGHI: MemImmOpc = SystemZ::CGHSI; break;
1106 case SystemZ::CLFIMux:
1107 case SystemZ::CLFI:
1108 if (isUInt<16>(MI.getOperand(1).getImm()))
1109 MemImmOpc = SystemZ::CLFHSI;
1110 break;
1111 case SystemZ::CLGFI:
1112 if (isUInt<16>(MI.getOperand(1).getImm()))
1113 MemImmOpc = SystemZ::CLGHSI;
1114 break;
1115 default: break;
1116 }
1117 if (MemImmOpc)
1118 return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(),
1119 get(MemImmOpc))
1120 .addFrameIndex(FrameIndex)
1121 .addImm(0)
1122 .addImm(MI.getOperand(1).getImm());
1123
1124 if (Opcode == SystemZ::LGDR || Opcode == SystemZ::LDGR) {
1125 bool Op0IsGPR = (Opcode == SystemZ::LGDR);
1126 bool Op1IsGPR = (Opcode == SystemZ::LDGR);
1127 // If we're spilling the destination of an LDGR or LGDR, store the
1128 // source register instead.
1129 if (OpNum == 0) {
1130 unsigned StoreOpcode = Op1IsGPR ? SystemZ::STG : SystemZ::STD;
1131 return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(),
1132 get(StoreOpcode))
1133 .add(MI.getOperand(1))
1134 .addFrameIndex(FrameIndex)
1135 .addImm(0)
1136 .addReg(0);
1137 }
1138 // If we're spilling the source of an LDGR or LGDR, load the
1139 // destination register instead.
1140 if (OpNum == 1) {
1141 unsigned LoadOpcode = Op0IsGPR ? SystemZ::LG : SystemZ::LD;
1142 return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(),
1143 get(LoadOpcode))
1144 .add(MI.getOperand(0))
1145 .addFrameIndex(FrameIndex)
1146 .addImm(0)
1147 .addReg(0);
1148 }
1149 }
1150
1151 // Look for cases where the source of a simple store or the destination
1152 // of a simple load is being spilled. Try to use MVC instead.
1153 //
1154 // Although MVC is in practice a fast choice in these cases, it is still
1155 // logically a bytewise copy. This means that we cannot use it if the
1156 // load or store is volatile. We also wouldn't be able to use MVC if
1157 // the two memories partially overlap, but that case cannot occur here,
1158 // because we know that one of the memories is a full frame index.
1159 //
1160 // For performance reasons, we also want to avoid using MVC if the addresses
1161 // might be equal. We don't worry about that case here, because spill slot
1162 // coloring happens later, and because we have special code to remove
1163 // MVCs that turn out to be redundant.
1164 if (OpNum == 0 && MI.hasOneMemOperand()) {
1165 MachineMemOperand *MMO = *MI.memoperands_begin();
1166 if (MMO->getSize() == Size && !MMO->isVolatile() && !MMO->isAtomic()) {
1167 // Handle conversion of loads.
1169 return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(),
1170 get(SystemZ::MVC))
1171 .addFrameIndex(FrameIndex)
1172 .addImm(0)
1173 .addImm(Size)
1174 .add(MI.getOperand(1))
1175 .addImm(MI.getOperand(2).getImm())
1176 .addMemOperand(MMO);
1177 }
1178 // Handle conversion of stores.
1180 return BuildMI(*InsertPt->getParent(), InsertPt, MI.getDebugLoc(),
1181 get(SystemZ::MVC))
1182 .add(MI.getOperand(1))
1183 .addImm(MI.getOperand(2).getImm())
1184 .addImm(Size)
1185 .addFrameIndex(FrameIndex)
1186 .addImm(0)
1187 .addMemOperand(MMO);
1188 }
1189 }
1190 }
1191
1192 // If the spilled operand is the final one or the instruction is
1193 // commutable, try to change <INSN>R into <INSN>. Don't introduce a def of
1194 // CC if it is live and MI does not define it.
1195 unsigned NumOps = MI.getNumExplicitOperands();
1196 int MemOpcode = SystemZ::getMemOpcode(Opcode);
1197 if (MemOpcode == -1 ||
1198 (CCLiveAtMI && !MI.definesRegister(SystemZ::CC) &&
1199 get(MemOpcode).hasImplicitDefOfPhysReg(SystemZ::CC)))
1200 return nullptr;
1201
1202 // Check if all other vregs have a usable allocation in the case of vector
1203 // to FP conversion.
1204 const MCInstrDesc &MCID = MI.getDesc();
1205 for (unsigned I = 0, E = MCID.getNumOperands(); I != E; ++I) {
1206 const MCOperandInfo &MCOI = MCID.operands()[I];
1207 if (MCOI.OperandType != MCOI::OPERAND_REGISTER || I == OpNum)
1208 continue;
1209 const TargetRegisterClass *RC = TRI->getRegClass(MCOI.RegClass);
1210 if (RC == &SystemZ::VR32BitRegClass || RC == &SystemZ::VR64BitRegClass) {
1211 Register Reg = MI.getOperand(I).getReg();
1212 Register PhysReg = Reg.isVirtual()
1213 ? (VRM ? Register(VRM->getPhys(Reg)) : Register())
1214 : Reg;
1215 if (!PhysReg ||
1216 !(SystemZ::FP32BitRegClass.contains(PhysReg) ||
1217 SystemZ::FP64BitRegClass.contains(PhysReg) ||
1218 SystemZ::VF128BitRegClass.contains(PhysReg)))
1219 return nullptr;
1220 }
1221 }
1222 // Fused multiply and add/sub need to have the same dst and accumulator reg.
1223 bool FusedFPOp = (Opcode == SystemZ::WFMADB || Opcode == SystemZ::WFMASB ||
1224 Opcode == SystemZ::WFMSDB || Opcode == SystemZ::WFMSSB);
1225 if (FusedFPOp) {
1226 Register DstReg = VRM->getPhys(MI.getOperand(0).getReg());
1227 Register AccReg = VRM->getPhys(MI.getOperand(3).getReg());
1228 if (OpNum == 0 || OpNum == 3 || DstReg != AccReg)
1229 return nullptr;
1230 }
1231
1232 // Try to swap compare operands if possible.
1233 bool NeedsCommute = false;
1234 if ((MI.getOpcode() == SystemZ::CR || MI.getOpcode() == SystemZ::CGR ||
1235 MI.getOpcode() == SystemZ::CLR || MI.getOpcode() == SystemZ::CLGR ||
1236 MI.getOpcode() == SystemZ::WFCDB || MI.getOpcode() == SystemZ::WFCSB ||
1237 MI.getOpcode() == SystemZ::WFKDB || MI.getOpcode() == SystemZ::WFKSB) &&
1238 OpNum == 0 && prepareCompareSwapOperands(MI))
1239 NeedsCommute = true;
1240
1241 bool CCOperands = false;
1242 if (MI.getOpcode() == SystemZ::LOCRMux || MI.getOpcode() == SystemZ::LOCGR ||
1243 MI.getOpcode() == SystemZ::SELRMux || MI.getOpcode() == SystemZ::SELGR) {
1244 assert(MI.getNumOperands() == 6 && NumOps == 5 &&
1245 "LOCR/SELR instruction operands corrupt?");
1246 NumOps -= 2;
1247 CCOperands = true;
1248 }
1249
1250 // See if this is a 3-address instruction that is convertible to 2-address
1251 // and suitable for folding below. Only try this with virtual registers
1252 // and a provided VRM (during regalloc).
1253 if (NumOps == 3 && SystemZ::getTargetMemOpcode(MemOpcode) != -1) {
1254 if (VRM == nullptr)
1255 return nullptr;
1256 else {
1257 Register DstReg = MI.getOperand(0).getReg();
1258 Register DstPhys =
1259 (DstReg.isVirtual() ? Register(VRM->getPhys(DstReg)) : DstReg);
1260 Register SrcReg = (OpNum == 2 ? MI.getOperand(1).getReg()
1261 : ((OpNum == 1 && MI.isCommutable())
1262 ? MI.getOperand(2).getReg()
1263 : Register()));
1264 if (DstPhys && !SystemZ::GRH32BitRegClass.contains(DstPhys) && SrcReg &&
1265 SrcReg.isVirtual() && DstPhys == VRM->getPhys(SrcReg))
1266 NeedsCommute = (OpNum == 1);
1267 else
1268 return nullptr;
1269 }
1270 }
1271
1272 if ((OpNum == NumOps - 1) || NeedsCommute || FusedFPOp) {
1273 const MCInstrDesc &MemDesc = get(MemOpcode);
1274 uint64_t AccessBytes = SystemZII::getAccessSize(MemDesc.TSFlags);
1275 assert(AccessBytes != 0 && "Size of access should be known");
1276 assert(AccessBytes <= Size && "Access outside the frame index");
1277 uint64_t Offset = Size - AccessBytes;
1278 MachineInstrBuilder MIB = BuildMI(*InsertPt->getParent(), InsertPt,
1279 MI.getDebugLoc(), get(MemOpcode));
1280 if (MI.isCompare()) {
1281 assert(NumOps == 2 && "Expected 2 register operands for a compare.");
1282 MIB.add(MI.getOperand(NeedsCommute ? 1 : 0));
1283 }
1284 else if (FusedFPOp) {
1285 MIB.add(MI.getOperand(0));
1286 MIB.add(MI.getOperand(3));
1287 MIB.add(MI.getOperand(OpNum == 1 ? 2 : 1));
1288 }
1289 else {
1290 MIB.add(MI.getOperand(0));
1291 if (NeedsCommute)
1292 MIB.add(MI.getOperand(2));
1293 else
1294 for (unsigned I = 1; I < OpNum; ++I)
1295 MIB.add(MI.getOperand(I));
1296 }
1297 MIB.addFrameIndex(FrameIndex).addImm(Offset);
1298 if (MemDesc.TSFlags & SystemZII::HasIndex)
1299 MIB.addReg(0);
1300 if (CCOperands) {
1301 unsigned CCValid = MI.getOperand(NumOps).getImm();
1302 unsigned CCMask = MI.getOperand(NumOps + 1).getImm();
1303 MIB.addImm(CCValid);
1304 MIB.addImm(NeedsCommute ? CCMask ^ CCValid : CCMask);
1305 }
1306 if (MIB->definesRegister(SystemZ::CC) &&
1307 (!MI.definesRegister(SystemZ::CC) ||
1308 MI.registerDefIsDead(SystemZ::CC))) {
1309 MIB->addRegisterDead(SystemZ::CC, TRI);
1310 if (CCLiveRange)
1311 CCLiveRange->createDeadDef(MISlot, LIS->getVNInfoAllocator());
1312 }
1313 // Constrain the register classes if converted from a vector opcode. The
1314 // allocated regs are in an FP reg-class per previous check above.
1315 for (const MachineOperand &MO : MIB->operands())
1316 if (MO.isReg() && MO.getReg().isVirtual()) {
1317 Register Reg = MO.getReg();
1318 if (MRI.getRegClass(Reg) == &SystemZ::VR32BitRegClass)
1319 MRI.setRegClass(Reg, &SystemZ::FP32BitRegClass);
1320 else if (MRI.getRegClass(Reg) == &SystemZ::VR64BitRegClass)
1321 MRI.setRegClass(Reg, &SystemZ::FP64BitRegClass);
1322 else if (MRI.getRegClass(Reg) == &SystemZ::VR128BitRegClass)
1323 MRI.setRegClass(Reg, &SystemZ::VF128BitRegClass);
1324 }
1325
1326 transferDeadCC(&MI, MIB);
1329 return MIB;
1330 }
1331
1332 return nullptr;
1333}
1334
1337 MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
1338 LiveIntervals *LIS) const {
1339 return nullptr;
1340}
1341
1343 switch (MI.getOpcode()) {
1344 case SystemZ::L128:
1345 splitMove(MI, SystemZ::LG);
1346 return true;
1347
1348 case SystemZ::ST128:
1349 splitMove(MI, SystemZ::STG);
1350 return true;
1351
1352 case SystemZ::LX:
1353 splitMove(MI, SystemZ::LD);
1354 return true;
1355
1356 case SystemZ::STX:
1357 splitMove(MI, SystemZ::STD);
1358 return true;
1359
1360 case SystemZ::LBMux:
1361 expandRXYPseudo(MI, SystemZ::LB, SystemZ::LBH);
1362 return true;
1363
1364 case SystemZ::LHMux:
1365 expandRXYPseudo(MI, SystemZ::LH, SystemZ::LHH);
1366 return true;
1367
1368 case SystemZ::LLCRMux:
1369 expandZExtPseudo(MI, SystemZ::LLCR, 8);
1370 return true;
1371
1372 case SystemZ::LLHRMux:
1373 expandZExtPseudo(MI, SystemZ::LLHR, 16);
1374 return true;
1375
1376 case SystemZ::LLCMux:
1377 expandRXYPseudo(MI, SystemZ::LLC, SystemZ::LLCH);
1378 return true;
1379
1380 case SystemZ::LLHMux:
1381 expandRXYPseudo(MI, SystemZ::LLH, SystemZ::LLHH);
1382 return true;
1383
1384 case SystemZ::LMux:
1385 expandRXYPseudo(MI, SystemZ::L, SystemZ::LFH);
1386 return true;
1387
1388 case SystemZ::LOCMux:
1389 expandLOCPseudo(MI, SystemZ::LOC, SystemZ::LOCFH);
1390 return true;
1391
1392 case SystemZ::LOCHIMux:
1393 expandLOCPseudo(MI, SystemZ::LOCHI, SystemZ::LOCHHI);
1394 return true;
1395
1396 case SystemZ::STCMux:
1397 expandRXYPseudo(MI, SystemZ::STC, SystemZ::STCH);
1398 return true;
1399
1400 case SystemZ::STHMux:
1401 expandRXYPseudo(MI, SystemZ::STH, SystemZ::STHH);
1402 return true;
1403
1404 case SystemZ::STMux:
1405 expandRXYPseudo(MI, SystemZ::ST, SystemZ::STFH);
1406 return true;
1407
1408 case SystemZ::STOCMux:
1409 expandLOCPseudo(MI, SystemZ::STOC, SystemZ::STOCFH);
1410 return true;
1411
1412 case SystemZ::LHIMux:
1413 expandRIPseudo(MI, SystemZ::LHI, SystemZ::IIHF, true);
1414 return true;
1415
1416 case SystemZ::IIFMux:
1417 expandRIPseudo(MI, SystemZ::IILF, SystemZ::IIHF, false);
1418 return true;
1419
1420 case SystemZ::IILMux:
1421 expandRIPseudo(MI, SystemZ::IILL, SystemZ::IIHL, false);
1422 return true;
1423
1424 case SystemZ::IIHMux:
1425 expandRIPseudo(MI, SystemZ::IILH, SystemZ::IIHH, false);
1426 return true;
1427
1428 case SystemZ::NIFMux:
1429 expandRIPseudo(MI, SystemZ::NILF, SystemZ::NIHF, false);
1430 return true;
1431
1432 case SystemZ::NILMux:
1433 expandRIPseudo(MI, SystemZ::NILL, SystemZ::NIHL, false);
1434 return true;
1435
1436 case SystemZ::NIHMux:
1437 expandRIPseudo(MI, SystemZ::NILH, SystemZ::NIHH, false);
1438 return true;
1439
1440 case SystemZ::OIFMux:
1441 expandRIPseudo(MI, SystemZ::OILF, SystemZ::OIHF, false);
1442 return true;
1443
1444 case SystemZ::OILMux:
1445 expandRIPseudo(MI, SystemZ::OILL, SystemZ::OIHL, false);
1446 return true;
1447
1448 case SystemZ::OIHMux:
1449 expandRIPseudo(MI, SystemZ::OILH, SystemZ::OIHH, false);
1450 return true;
1451
1452 case SystemZ::XIFMux:
1453 expandRIPseudo(MI, SystemZ::XILF, SystemZ::XIHF, false);
1454 return true;
1455
1456 case SystemZ::TMLMux:
1457 expandRIPseudo(MI, SystemZ::TMLL, SystemZ::TMHL, false);
1458 return true;
1459
1460 case SystemZ::TMHMux:
1461 expandRIPseudo(MI, SystemZ::TMLH, SystemZ::TMHH, false);
1462 return true;
1463
1464 case SystemZ::AHIMux:
1465 expandRIPseudo(MI, SystemZ::AHI, SystemZ::AIH, false);
1466 return true;
1467
1468 case SystemZ::AHIMuxK:
1469 expandRIEPseudo(MI, SystemZ::AHI, SystemZ::AHIK, SystemZ::AIH);
1470 return true;
1471
1472 case SystemZ::AFIMux:
1473 expandRIPseudo(MI, SystemZ::AFI, SystemZ::AIH, false);
1474 return true;
1475
1476 case SystemZ::CHIMux:
1477 expandRIPseudo(MI, SystemZ::CHI, SystemZ::CIH, false);
1478 return true;
1479
1480 case SystemZ::CFIMux:
1481 expandRIPseudo(MI, SystemZ::CFI, SystemZ::CIH, false);
1482 return true;
1483
1484 case SystemZ::CLFIMux:
1485 expandRIPseudo(MI, SystemZ::CLFI, SystemZ::CLIH, false);
1486 return true;
1487
1488 case SystemZ::CMux:
1489 expandRXYPseudo(MI, SystemZ::C, SystemZ::CHF);
1490 return true;
1491
1492 case SystemZ::CLMux:
1493 expandRXYPseudo(MI, SystemZ::CL, SystemZ::CLHF);
1494 return true;
1495
1496 case SystemZ::RISBMux: {
1497 bool DestIsHigh = SystemZ::isHighReg(MI.getOperand(0).getReg());
1498 bool SrcIsHigh = SystemZ::isHighReg(MI.getOperand(2).getReg());
1499 if (SrcIsHigh == DestIsHigh)
1500 MI.setDesc(get(DestIsHigh ? SystemZ::RISBHH : SystemZ::RISBLL));
1501 else {
1502 MI.setDesc(get(DestIsHigh ? SystemZ::RISBHL : SystemZ::RISBLH));
1503 MI.getOperand(5).setImm(MI.getOperand(5).getImm() ^ 32);
1504 }
1505 return true;
1506 }
1507
1508 case SystemZ::ADJDYNALLOC:
1509 splitAdjDynAlloc(MI);
1510 return true;
1511
1512 case TargetOpcode::LOAD_STACK_GUARD:
1513 expandLoadStackGuard(&MI);
1514 return true;
1515
1516 default:
1517 return false;
1518 }
1519}
1520
1522 if (MI.isInlineAsm()) {
1523 const MachineFunction *MF = MI.getParent()->getParent();
1524 const char *AsmStr = MI.getOperand(0).getSymbolName();
1525 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
1526 }
1527 else if (MI.getOpcode() == SystemZ::PATCHPOINT)
1529 else if (MI.getOpcode() == SystemZ::STACKMAP)
1530 return MI.getOperand(1).getImm();
1531 else if (MI.getOpcode() == SystemZ::FENTRY_CALL)
1532 return 6;
1533
1534 return MI.getDesc().getSize();
1535}
1536
1539 switch (MI.getOpcode()) {
1540 case SystemZ::BR:
1541 case SystemZ::BI:
1542 case SystemZ::J:
1543 case SystemZ::JG:
1545 SystemZ::CCMASK_ANY, &MI.getOperand(0));
1546
1547 case SystemZ::BRC:
1548 case SystemZ::BRCL:
1549 return SystemZII::Branch(SystemZII::BranchNormal, MI.getOperand(0).getImm(),
1550 MI.getOperand(1).getImm(), &MI.getOperand(2));
1551
1552 case SystemZ::BRCT:
1553 case SystemZ::BRCTH:
1555 SystemZ::CCMASK_CMP_NE, &MI.getOperand(2));
1556
1557 case SystemZ::BRCTG:
1559 SystemZ::CCMASK_CMP_NE, &MI.getOperand(2));
1560
1561 case SystemZ::CIJ:
1562 case SystemZ::CRJ:
1564 MI.getOperand(2).getImm(), &MI.getOperand(3));
1565
1566 case SystemZ::CLIJ:
1567 case SystemZ::CLRJ:
1569 MI.getOperand(2).getImm(), &MI.getOperand(3));
1570
1571 case SystemZ::CGIJ:
1572 case SystemZ::CGRJ:
1574 MI.getOperand(2).getImm(), &MI.getOperand(3));
1575
1576 case SystemZ::CLGIJ:
1577 case SystemZ::CLGRJ:
1579 MI.getOperand(2).getImm(), &MI.getOperand(3));
1580
1581 case SystemZ::INLINEASM_BR:
1582 // Don't try to analyze asm goto, so pass nullptr as branch target argument.
1583 return SystemZII::Branch(SystemZII::AsmGoto, 0, 0, nullptr);
1584
1585 default:
1586 llvm_unreachable("Unrecognized branch opcode");
1587 }
1588}
1589
1591 unsigned &LoadOpcode,
1592 unsigned &StoreOpcode) const {
1593 if (RC == &SystemZ::GR32BitRegClass || RC == &SystemZ::ADDR32BitRegClass) {
1594 LoadOpcode = SystemZ::L;
1595 StoreOpcode = SystemZ::ST;
1596 } else if (RC == &SystemZ::GRH32BitRegClass) {
1597 LoadOpcode = SystemZ::LFH;
1598 StoreOpcode = SystemZ::STFH;
1599 } else if (RC == &SystemZ::GRX32BitRegClass) {
1600 LoadOpcode = SystemZ::LMux;
1601 StoreOpcode = SystemZ::STMux;
1602 } else if (RC == &SystemZ::GR64BitRegClass ||
1603 RC == &SystemZ::ADDR64BitRegClass) {
1604 LoadOpcode = SystemZ::LG;
1605 StoreOpcode = SystemZ::STG;
1606 } else if (RC == &SystemZ::GR128BitRegClass ||
1607 RC == &SystemZ::ADDR128BitRegClass) {
1608 LoadOpcode = SystemZ::L128;
1609 StoreOpcode = SystemZ::ST128;
1610 } else if (RC == &SystemZ::FP32BitRegClass) {
1611 LoadOpcode = SystemZ::LE;
1612 StoreOpcode = SystemZ::STE;
1613 } else if (RC == &SystemZ::FP64BitRegClass) {
1614 LoadOpcode = SystemZ::LD;
1615 StoreOpcode = SystemZ::STD;
1616 } else if (RC == &SystemZ::FP128BitRegClass) {
1617 LoadOpcode = SystemZ::LX;
1618 StoreOpcode = SystemZ::STX;
1619 } else if (RC == &SystemZ::VR32BitRegClass) {
1620 LoadOpcode = SystemZ::VL32;
1621 StoreOpcode = SystemZ::VST32;
1622 } else if (RC == &SystemZ::VR64BitRegClass) {
1623 LoadOpcode = SystemZ::VL64;
1624 StoreOpcode = SystemZ::VST64;
1625 } else if (RC == &SystemZ::VF128BitRegClass ||
1626 RC == &SystemZ::VR128BitRegClass) {
1627 LoadOpcode = SystemZ::VL;
1628 StoreOpcode = SystemZ::VST;
1629 } else
1630 llvm_unreachable("Unsupported regclass to load or store");
1631}
1632
1634 int64_t Offset,
1635 const MachineInstr *MI) const {
1636 const MCInstrDesc &MCID = get(Opcode);
1637 int64_t Offset2 = (MCID.TSFlags & SystemZII::Is128Bit ? Offset + 8 : Offset);
1638 if (isUInt<12>(Offset) && isUInt<12>(Offset2)) {
1639 // Get the instruction to use for unsigned 12-bit displacements.
1640 int Disp12Opcode = SystemZ::getDisp12Opcode(Opcode);
1641 if (Disp12Opcode >= 0)
1642 return Disp12Opcode;
1643
1644 // All address-related instructions can use unsigned 12-bit
1645 // displacements.
1646 return Opcode;
1647 }
1648 if (isInt<20>(Offset) && isInt<20>(Offset2)) {
1649 // Get the instruction to use for signed 20-bit displacements.
1650 int Disp20Opcode = SystemZ::getDisp20Opcode(Opcode);
1651 if (Disp20Opcode >= 0)
1652 return Disp20Opcode;
1653
1654 // Check whether Opcode allows signed 20-bit displacements.
1656 return Opcode;
1657
1658 // If a VR32/VR64 reg ended up in an FP register, use the FP opcode.
1659 if (MI && MI->getOperand(0).isReg()) {
1660 Register Reg = MI->getOperand(0).getReg();
1661 if (Reg.isPhysical() && SystemZMC::getFirstReg(Reg) < 16) {
1662 switch (Opcode) {
1663 case SystemZ::VL32:
1664 return SystemZ::LEY;
1665 case SystemZ::VST32:
1666 return SystemZ::STEY;
1667 case SystemZ::VL64:
1668 return SystemZ::LDY;
1669 case SystemZ::VST64:
1670 return SystemZ::STDY;
1671 default: break;
1672 }
1673 }
1674 }
1675 }
1676 return 0;
1677}
1678
1680 const MCInstrDesc &MCID = get(Opcode);
1682 return SystemZ::getDisp12Opcode(Opcode) >= 0;
1683 return SystemZ::getDisp20Opcode(Opcode) >= 0;
1684}
1685
1686unsigned SystemZInstrInfo::getLoadAndTest(unsigned Opcode) const {
1687 switch (Opcode) {
1688 case SystemZ::L: return SystemZ::LT;
1689 case SystemZ::LY: return SystemZ::LT;
1690 case SystemZ::LG: return SystemZ::LTG;
1691 case SystemZ::LGF: return SystemZ::LTGF;
1692 case SystemZ::LR: return SystemZ::LTR;
1693 case SystemZ::LGFR: return SystemZ::LTGFR;
1694 case SystemZ::LGR: return SystemZ::LTGR;
1695 case SystemZ::LCDFR: return SystemZ::LCDBR;
1696 case SystemZ::LPDFR: return SystemZ::LPDBR;
1697 case SystemZ::LNDFR: return SystemZ::LNDBR;
1698 case SystemZ::LCDFR_32: return SystemZ::LCEBR;
1699 case SystemZ::LPDFR_32: return SystemZ::LPEBR;
1700 case SystemZ::LNDFR_32: return SystemZ::LNEBR;
1701 // On zEC12 we prefer to use RISBGN. But if there is a chance to
1702 // actually use the condition code, we may turn it back into RISGB.
1703 // Note that RISBG is not really a "load-and-test" instruction,
1704 // but sets the same condition code values, so is OK to use here.
1705 case SystemZ::RISBGN: return SystemZ::RISBG;
1706 default: return 0;
1707 }
1708}
1709
1710bool SystemZInstrInfo::isRxSBGMask(uint64_t Mask, unsigned BitSize,
1711 unsigned &Start, unsigned &End) const {
1712 // Reject trivial all-zero masks.
1713 Mask &= allOnes(BitSize);
1714 if (Mask == 0)
1715 return false;
1716
1717 // Handle the 1+0+ or 0+1+0* cases. Start then specifies the index of
1718 // the msb and End specifies the index of the lsb.
1719 unsigned LSB, Length;
1720 if (isShiftedMask_64(Mask, LSB, Length)) {
1721 Start = 63 - (LSB + Length - 1);
1722 End = 63 - LSB;
1723 return true;
1724 }
1725
1726 // Handle the wrap-around 1+0+1+ cases. Start then specifies the msb
1727 // of the low 1s and End specifies the lsb of the high 1s.
1728 if (isShiftedMask_64(Mask ^ allOnes(BitSize), LSB, Length)) {
1729 assert(LSB > 0 && "Bottom bit must be set");
1730 assert(LSB + Length < BitSize && "Top bit must be set");
1731 Start = 63 - (LSB - 1);
1732 End = 63 - (LSB + Length);
1733 return true;
1734 }
1735
1736 return false;
1737}
1738
1739unsigned SystemZInstrInfo::getFusedCompare(unsigned Opcode,
1741 const MachineInstr *MI) const {
1742 switch (Opcode) {
1743 case SystemZ::CHI:
1744 case SystemZ::CGHI:
1745 if (!(MI && isInt<8>(MI->getOperand(1).getImm())))
1746 return 0;
1747 break;
1748 case SystemZ::CLFI:
1749 case SystemZ::CLGFI:
1750 if (!(MI && isUInt<8>(MI->getOperand(1).getImm())))
1751 return 0;
1752 break;
1753 case SystemZ::CL:
1754 case SystemZ::CLG:
1755 if (!STI.hasMiscellaneousExtensions())
1756 return 0;
1757 if (!(MI && MI->getOperand(3).getReg() == 0))
1758 return 0;
1759 break;
1760 }
1761 switch (Type) {
1763 switch (Opcode) {
1764 case SystemZ::CR:
1765 return SystemZ::CRJ;
1766 case SystemZ::CGR:
1767 return SystemZ::CGRJ;
1768 case SystemZ::CHI:
1769 return SystemZ::CIJ;
1770 case SystemZ::CGHI:
1771 return SystemZ::CGIJ;
1772 case SystemZ::CLR:
1773 return SystemZ::CLRJ;
1774 case SystemZ::CLGR:
1775 return SystemZ::CLGRJ;
1776 case SystemZ::CLFI:
1777 return SystemZ::CLIJ;
1778 case SystemZ::CLGFI:
1779 return SystemZ::CLGIJ;
1780 default:
1781 return 0;
1782 }
1784 switch (Opcode) {
1785 case SystemZ::CR:
1786 return SystemZ::CRBReturn;
1787 case SystemZ::CGR:
1788 return SystemZ::CGRBReturn;
1789 case SystemZ::CHI:
1790 return SystemZ::CIBReturn;
1791 case SystemZ::CGHI:
1792 return SystemZ::CGIBReturn;
1793 case SystemZ::CLR:
1794 return SystemZ::CLRBReturn;
1795 case SystemZ::CLGR:
1796 return SystemZ::CLGRBReturn;
1797 case SystemZ::CLFI:
1798 return SystemZ::CLIBReturn;
1799 case SystemZ::CLGFI:
1800 return SystemZ::CLGIBReturn;
1801 default:
1802 return 0;
1803 }
1805 switch (Opcode) {
1806 case SystemZ::CR:
1807 return SystemZ::CRBCall;
1808 case SystemZ::CGR:
1809 return SystemZ::CGRBCall;
1810 case SystemZ::CHI:
1811 return SystemZ::CIBCall;
1812 case SystemZ::CGHI:
1813 return SystemZ::CGIBCall;
1814 case SystemZ::CLR:
1815 return SystemZ::CLRBCall;
1816 case SystemZ::CLGR:
1817 return SystemZ::CLGRBCall;
1818 case SystemZ::CLFI:
1819 return SystemZ::CLIBCall;
1820 case SystemZ::CLGFI:
1821 return SystemZ::CLGIBCall;
1822 default:
1823 return 0;
1824 }
1826 switch (Opcode) {
1827 case SystemZ::CR:
1828 return SystemZ::CRT;
1829 case SystemZ::CGR:
1830 return SystemZ::CGRT;
1831 case SystemZ::CHI:
1832 return SystemZ::CIT;
1833 case SystemZ::CGHI:
1834 return SystemZ::CGIT;
1835 case SystemZ::CLR:
1836 return SystemZ::CLRT;
1837 case SystemZ::CLGR:
1838 return SystemZ::CLGRT;
1839 case SystemZ::CLFI:
1840 return SystemZ::CLFIT;
1841 case SystemZ::CLGFI:
1842 return SystemZ::CLGIT;
1843 case SystemZ::CL:
1844 return SystemZ::CLT;
1845 case SystemZ::CLG:
1846 return SystemZ::CLGT;
1847 default:
1848 return 0;
1849 }
1850 }
1851 return 0;
1852}
1853
1856 assert(MBBI->isCompare() && MBBI->getOperand(0).isReg() &&
1857 MBBI->getOperand(1).isReg() && !MBBI->mayLoad() &&
1858 "Not a compare reg/reg.");
1859
1861 bool CCLive = true;
1863 for (MachineInstr &MI : llvm::make_range(std::next(MBBI), MBB->end())) {
1864 if (MI.readsRegister(SystemZ::CC)) {
1865 unsigned Flags = MI.getDesc().TSFlags;
1866 if ((Flags & SystemZII::CCMaskFirst) || (Flags & SystemZII::CCMaskLast))
1867 CCUsers.push_back(&MI);
1868 else
1869 return false;
1870 }
1871 if (MI.definesRegister(SystemZ::CC)) {
1872 CCLive = false;
1873 break;
1874 }
1875 }
1876 if (CCLive) {
1878 LiveRegs.addLiveOuts(*MBB);
1879 if (!LiveRegs.available(SystemZ::CC))
1880 return false;
1881 }
1882
1883 // Update all CC users.
1884 for (unsigned Idx = 0; Idx < CCUsers.size(); ++Idx) {
1885 unsigned Flags = CCUsers[Idx]->getDesc().TSFlags;
1886 unsigned FirstOpNum = ((Flags & SystemZII::CCMaskFirst) ?
1887 0 : CCUsers[Idx]->getNumExplicitOperands() - 2);
1888 MachineOperand &CCMaskMO = CCUsers[Idx]->getOperand(FirstOpNum + 1);
1889 unsigned NewCCMask = SystemZ::reverseCCMask(CCMaskMO.getImm());
1890 CCMaskMO.setImm(NewCCMask);
1891 }
1892
1893 return true;
1894}
1895
1896unsigned SystemZ::reverseCCMask(unsigned CCMask) {
1897 return ((CCMask & SystemZ::CCMASK_CMP_EQ) |
1900 (CCMask & SystemZ::CCMASK_CMP_UO));
1901}
1902
1904 MachineFunction &MF = *MBB->getParent();
1906 MF.insert(std::next(MachineFunction::iterator(MBB)), NewMBB);
1907 return NewMBB;
1908}
1909
1913 NewMBB->splice(NewMBB->begin(), MBB,
1914 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
1916 return NewMBB;
1917}
1918
1922 NewMBB->splice(NewMBB->begin(), MBB, MI, MBB->end());
1924 return NewMBB;
1925}
1926
1927unsigned SystemZInstrInfo::getLoadAndTrap(unsigned Opcode) const {
1928 if (!STI.hasLoadAndTrap())
1929 return 0;
1930 switch (Opcode) {
1931 case SystemZ::L:
1932 case SystemZ::LY:
1933 return SystemZ::LAT;
1934 case SystemZ::LG:
1935 return SystemZ::LGAT;
1936 case SystemZ::LFH:
1937 return SystemZ::LFHAT;
1938 case SystemZ::LLGF:
1939 return SystemZ::LLGFAT;
1940 case SystemZ::LLGT:
1941 return SystemZ::LLGTAT;
1942 }
1943 return 0;
1944}
1945
1948 unsigned Reg, uint64_t Value) const {
1949 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
1950 unsigned Opcode = 0;
1951 if (isInt<16>(Value))
1952 Opcode = SystemZ::LGHI;
1953 else if (SystemZ::isImmLL(Value))
1954 Opcode = SystemZ::LLILL;
1955 else if (SystemZ::isImmLH(Value)) {
1956 Opcode = SystemZ::LLILH;
1957 Value >>= 16;
1958 }
1959 else if (isInt<32>(Value))
1960 Opcode = SystemZ::LGFI;
1961 if (Opcode) {
1962 BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
1963 return;
1964 }
1965
1967 assert (MRI.isSSA() && "Huge values only handled before reg-alloc .");
1968 Register Reg0 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
1969 Register Reg1 = MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
1970 BuildMI(MBB, MBBI, DL, get(SystemZ::IMPLICIT_DEF), Reg0);
1971 BuildMI(MBB, MBBI, DL, get(SystemZ::IIHF64), Reg1)
1972 .addReg(Reg0).addImm(Value >> 32);
1973 BuildMI(MBB, MBBI, DL, get(SystemZ::IILF64), Reg)
1974 .addReg(Reg1).addImm(Value & ((uint64_t(1) << 32) - 1));
1975}
1976
1978 StringRef &ErrInfo) const {
1979 const MCInstrDesc &MCID = MI.getDesc();
1980 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
1981 if (I >= MCID.getNumOperands())
1982 break;
1983 const MachineOperand &Op = MI.getOperand(I);
1984 const MCOperandInfo &MCOI = MCID.operands()[I];
1985 // Addressing modes have register and immediate operands. Op should be a
1986 // register (or frame index) operand if MCOI.RegClass contains a valid
1987 // register class, or an immediate otherwise.
1988 if (MCOI.OperandType == MCOI::OPERAND_MEMORY &&
1989 ((MCOI.RegClass != -1 && !Op.isReg() && !Op.isFI()) ||
1990 (MCOI.RegClass == -1 && !Op.isImm()))) {
1991 ErrInfo = "Addressing mode operands corrupt!";
1992 return false;
1993 }
1994 }
1995
1996 return true;
1997}
1998
2001 const MachineInstr &MIb) const {
2002
2003 if (!MIa.hasOneMemOperand() || !MIb.hasOneMemOperand())
2004 return false;
2005
2006 // If mem-operands show that the same address Value is used by both
2007 // instructions, check for non-overlapping offsets and widths. Not
2008 // sure if a register based analysis would be an improvement...
2009
2010 MachineMemOperand *MMOa = *MIa.memoperands_begin();
2011 MachineMemOperand *MMOb = *MIb.memoperands_begin();
2012 const Value *VALa = MMOa->getValue();
2013 const Value *VALb = MMOb->getValue();
2014 bool SameVal = (VALa && VALb && (VALa == VALb));
2015 if (!SameVal) {
2016 const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
2017 const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
2018 if (PSVa && PSVb && (PSVa == PSVb))
2019 SameVal = true;
2020 }
2021 if (SameVal) {
2022 int OffsetA = MMOa->getOffset(), OffsetB = MMOb->getOffset();
2023 LocationSize WidthA = MMOa->getSize(), WidthB = MMOb->getSize();
2024 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
2025 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
2026 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2027 if (LowWidth.hasValue() &&
2028 LowOffset + (int)LowWidth.getValue() <= HighOffset)
2029 return true;
2030 }
2031
2032 return false;
2033}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned RegSize
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
IRTranslator LLVM IR MI
A set of register units.
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag)
static void transferDeadCC(MachineInstr *OldMI, MachineInstr *NewMI)
static void transferMIFlag(MachineInstr *OldMI, MachineInstr *NewMI, MachineInstr::MIFlag Flag)
static int isSimpleMove(const MachineInstr &MI, int &FrameIndex, unsigned Flag)
static LogicOp interpretAndImmediate(unsigned Opcode)
static uint64_t allOnes(unsigned int Count)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
SlotIndexes * getSlotIndexes() const
VNInfo::Allocator & getVNInfoAllocator()
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
This class represents the liveness of a register, stack slot, etc.
Definition: LiveInterval.h:157
bool liveAt(SlotIndex index) const
Definition: LiveInterval.h:401
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
A set of register units used to track register liveness.
Definition: LiveRegUnits.h:30
bool available(MCPhysReg Reg) const
Returns true if no part of physical register Reg is live.
Definition: LiveRegUnits.h:116
void addLiveOuts(const MachineBasicBlock &MBB)
Adds registers living out of block MBB.
void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
bool hasValue() const
TypeSize getValue() const
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:237
ArrayRef< MCOperandInfo > operands() const
Definition: MCInstrDesc.h:239
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:85
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:97
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:91
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition: MCRegister.h:74
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
Definition: MachineInstr.h:377
bool registerDefIsDead(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Returns true if the register is dead in this machine instruction.
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
Definition: MachineInstr.h:790
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:660
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:775
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
void setFlag(MIFlag Flag)
Set a MI flag.
Definition: MachineInstr.h:384
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:554
MachineOperand * findRegisterDefOperand(Register Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
const PseudoSourceValue * getPseudoValue() const
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
const Value * getValue() const
Return the base address of the memory access.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MI-level patchpoint operands.
Definition: StackMaps.h:76
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Definition: StackMaps.h:104
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:91
SlotIndex - An opaque wrapper around machine indexes.
Definition: SlotIndexes.h:68
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
Definition: SlotIndexes.h:240
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
Definition: SlotIndexes.h:371
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
A SystemZ-specific class detailing special use registers particular for calling conventions.
unsigned getLoadAndTrap(unsigned Opcode) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
unsigned getLoadAndTest(unsigned Opcode) const
bool isPredicable(const MachineInstr &MI) const override
bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex, int &SrcFrameIndex) const override
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset, const MachineInstr *MI=nullptr) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
SystemZInstrInfo(SystemZSubtarget &STI)
bool hasDisplacementPairInsn(unsigned Opcode) const
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned CommuteOpIdx1, unsigned CommuteOpIdx2) const override
Commutes the operands in the given instruction by changing the operands order and/or changing the ins...
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
unsigned getFusedCompare(unsigned Opcode, SystemZII::FusedCompareType Type, const MachineInstr *MI=nullptr) const
bool expandPostRAPseudo(MachineInstr &MBBI) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode) const
bool isRxSBGMask(uint64_t Mask, unsigned BitSize, unsigned &Start, unsigned &End) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned Reg, uint64_t Value) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition: VirtRegMap.h:105
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ OPERAND_REGISTER
Definition: MCInstrDesc.h:61
@ OPERAND_MEMORY
Definition: MCInstrDesc.h:62
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
static unsigned getAccessSize(unsigned int Flags)
unsigned getFirstReg(unsigned Reg)
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
int getTargetMemOpcode(uint16_t Opcode)
const unsigned CCMASK_CMP_GT
Definition: SystemZ.h:37
const unsigned CCMASK_ANY
Definition: SystemZ.h:31
static bool isImmLL(uint64_t Val)
Definition: SystemZ.h:161
static bool isImmLH(uint64_t Val)
Definition: SystemZ.h:166
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
unsigned reverseCCMask(unsigned CCMask)
const unsigned IPM_CC
Definition: SystemZ.h:112
const unsigned CCMASK_CMP_EQ
Definition: SystemZ.h:35
const unsigned CCMASK_ICMP
Definition: SystemZ.h:47
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_CMP_LT
Definition: SystemZ.h:36
const unsigned CCMASK_CMP_NE
Definition: SystemZ.h:38
bool isHighReg(unsigned int Reg)
const unsigned CCMASK_CMP_UO
Definition: SystemZ.h:43
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:456
@ Length
Definition: DWP.cpp:456
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
Definition: MathExtras.h:258
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
Definition: STLExtras.h:1714
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getUndefRegState(bool B)
@ And
Bitwise or logical AND of integers.
unsigned getKillRegState(bool B)