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