10b57cec5SDimitry Andric //===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains the SystemZ implementation of the TargetInstrInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric #include "SystemZ.h"
170b57cec5SDimitry Andric #include "SystemZRegisterInfo.h"
180b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
230b57cec5SDimitry Andric #include <cstdint>
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER
260b57cec5SDimitry Andric #include "SystemZGenInstrInfo.inc"
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric namespace llvm {
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric class SystemZSubtarget;
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric namespace SystemZII {
330b57cec5SDimitry Andric
340b57cec5SDimitry Andric enum {
350b57cec5SDimitry Andric // See comments in SystemZInstrFormats.td.
360b57cec5SDimitry Andric SimpleBDXLoad = (1 << 0),
370b57cec5SDimitry Andric SimpleBDXStore = (1 << 1),
380b57cec5SDimitry Andric Has20BitOffset = (1 << 2),
390b57cec5SDimitry Andric HasIndex = (1 << 3),
400b57cec5SDimitry Andric Is128Bit = (1 << 4),
410b57cec5SDimitry Andric AccessSizeMask = (31 << 5),
420b57cec5SDimitry Andric AccessSizeShift = 5,
430b57cec5SDimitry Andric CCValuesMask = (15 << 10),
440b57cec5SDimitry Andric CCValuesShift = 10,
450b57cec5SDimitry Andric CompareZeroCCMaskMask = (15 << 14),
460b57cec5SDimitry Andric CompareZeroCCMaskShift = 14,
470b57cec5SDimitry Andric CCMaskFirst = (1 << 18),
480b57cec5SDimitry Andric CCMaskLast = (1 << 19),
49480093f4SDimitry Andric IsLogical = (1 << 20),
5081ad6265SDimitry Andric CCIfNoSignedWrap = (1 << 21)
510b57cec5SDimitry Andric };
520b57cec5SDimitry Andric
getAccessSize(unsigned int Flags)530b57cec5SDimitry Andric static inline unsigned getAccessSize(unsigned int Flags) {
540b57cec5SDimitry Andric return (Flags & AccessSizeMask) >> AccessSizeShift;
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric
getCCValues(unsigned int Flags)570b57cec5SDimitry Andric static inline unsigned getCCValues(unsigned int Flags) {
580b57cec5SDimitry Andric return (Flags & CCValuesMask) >> CCValuesShift;
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric
getCompareZeroCCMask(unsigned int Flags)610b57cec5SDimitry Andric static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
620b57cec5SDimitry Andric return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric
650b57cec5SDimitry Andric // SystemZ MachineOperand target flags.
660b57cec5SDimitry Andric enum {
670b57cec5SDimitry Andric // Masks out the bits for the access model.
680b57cec5SDimitry Andric MO_SYMBOL_MODIFIER = (3 << 0),
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric // @GOT (aka @GOTENT)
710b57cec5SDimitry Andric MO_GOT = (1 << 0),
720b57cec5SDimitry Andric
730b57cec5SDimitry Andric // @INDNTPOFF
740b57cec5SDimitry Andric MO_INDNTPOFF = (2 << 0)
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric
7706c3fb27SDimitry Andric // z/OS XPLink specific: classifies the types of
7806c3fb27SDimitry Andric // accesses to the ADA (Associated Data Area).
7906c3fb27SDimitry Andric // These enums contains values that overlap with the above MO_ enums,
8006c3fb27SDimitry Andric // but that's fine since the above enums are used with ELF,
8106c3fb27SDimitry Andric // while these values are used with z/OS.
8206c3fb27SDimitry Andric enum {
8306c3fb27SDimitry Andric MO_ADA_DATA_SYMBOL_ADDR = 1,
8406c3fb27SDimitry Andric MO_ADA_INDIRECT_FUNC_DESC,
8506c3fb27SDimitry Andric MO_ADA_DIRECT_FUNC_DESC,
8606c3fb27SDimitry Andric };
8706c3fb27SDimitry Andric
880b57cec5SDimitry Andric // Classifies a branch.
890b57cec5SDimitry Andric enum BranchType {
900b57cec5SDimitry Andric // An instruction that branches on the current value of CC.
910b57cec5SDimitry Andric BranchNormal,
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric // An instruction that peforms a 32-bit signed comparison and branches
940b57cec5SDimitry Andric // on the result.
950b57cec5SDimitry Andric BranchC,
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric // An instruction that peforms a 32-bit unsigned comparison and branches
980b57cec5SDimitry Andric // on the result.
990b57cec5SDimitry Andric BranchCL,
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric // An instruction that peforms a 64-bit signed comparison and branches
1020b57cec5SDimitry Andric // on the result.
1030b57cec5SDimitry Andric BranchCG,
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andric // An instruction that peforms a 64-bit unsigned comparison and branches
1060b57cec5SDimitry Andric // on the result.
1070b57cec5SDimitry Andric BranchCLG,
1080b57cec5SDimitry Andric
1090b57cec5SDimitry Andric // An instruction that decrements a 32-bit register and branches if
1100b57cec5SDimitry Andric // the result is nonzero.
1110b57cec5SDimitry Andric BranchCT,
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric // An instruction that decrements a 64-bit register and branches if
1140b57cec5SDimitry Andric // the result is nonzero.
1150b57cec5SDimitry Andric BranchCTG,
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric // An instruction representing an asm goto statement.
1180b57cec5SDimitry Andric AsmGoto
1190b57cec5SDimitry Andric };
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andric // Information about a branch instruction.
1220b57cec5SDimitry Andric class Branch {
1230b57cec5SDimitry Andric // The target of the branch. In case of INLINEASM_BR, this is nullptr.
1240b57cec5SDimitry Andric const MachineOperand *Target;
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric public:
1270b57cec5SDimitry Andric // The type of the branch.
1280b57cec5SDimitry Andric BranchType Type;
1290b57cec5SDimitry Andric
1300b57cec5SDimitry Andric // CCMASK_<N> is set if CC might be equal to N.
1310b57cec5SDimitry Andric unsigned CCValid;
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric // CCMASK_<N> is set if the branch should be taken when CC == N.
1340b57cec5SDimitry Andric unsigned CCMask;
1350b57cec5SDimitry Andric
Branch(BranchType type,unsigned ccValid,unsigned ccMask,const MachineOperand * target)1360b57cec5SDimitry Andric Branch(BranchType type, unsigned ccValid, unsigned ccMask,
1370b57cec5SDimitry Andric const MachineOperand *target)
1380b57cec5SDimitry Andric : Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {}
1390b57cec5SDimitry Andric
isIndirect()1400b57cec5SDimitry Andric bool isIndirect() { return Target != nullptr && Target->isReg(); }
hasMBBTarget()1410b57cec5SDimitry Andric bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); }
getMBBTarget()1420b57cec5SDimitry Andric MachineBasicBlock *getMBBTarget() {
1430b57cec5SDimitry Andric return hasMBBTarget() ? Target->getMBB() : nullptr;
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric };
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric // Kinds of fused compares in compare-and-* instructions. Together with type
1480b57cec5SDimitry Andric // of the converted compare, this identifies the compare-and-*
1490b57cec5SDimitry Andric // instruction.
1500b57cec5SDimitry Andric enum FusedCompareType {
1510b57cec5SDimitry Andric // Relative branch - CRJ etc.
1520b57cec5SDimitry Andric CompareAndBranch,
1530b57cec5SDimitry Andric
1540b57cec5SDimitry Andric // Indirect branch, used for return - CRBReturn etc.
1550b57cec5SDimitry Andric CompareAndReturn,
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric // Indirect branch, used for sibcall - CRBCall etc.
1580b57cec5SDimitry Andric CompareAndSibcall,
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric // Trap
1610b57cec5SDimitry Andric CompareAndTrap
1620b57cec5SDimitry Andric };
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric } // end namespace SystemZII
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andric namespace SystemZ {
1670b57cec5SDimitry Andric int getTwoOperandOpcode(uint16_t Opcode);
1680b57cec5SDimitry Andric int getTargetMemOpcode(uint16_t Opcode);
1695ffd83dbSDimitry Andric
1705ffd83dbSDimitry Andric // Return a version of comparison CC mask CCMask in which the LT and GT
1715ffd83dbSDimitry Andric // actions are swapped.
1725ffd83dbSDimitry Andric unsigned reverseCCMask(unsigned CCMask);
1735ffd83dbSDimitry Andric
1745ffd83dbSDimitry Andric // Create a new basic block after MBB.
1755ffd83dbSDimitry Andric MachineBasicBlock *emitBlockAfter(MachineBasicBlock *MBB);
1765ffd83dbSDimitry Andric // Split MBB after MI and return the new block (the one that contains
1775ffd83dbSDimitry Andric // instructions after MI).
1785ffd83dbSDimitry Andric MachineBasicBlock *splitBlockAfter(MachineBasicBlock::iterator MI,
1795ffd83dbSDimitry Andric MachineBasicBlock *MBB);
1805ffd83dbSDimitry Andric // Split MBB before MI and return the new block (the one that contains MI).
1815ffd83dbSDimitry Andric MachineBasicBlock *splitBlockBefore(MachineBasicBlock::iterator MI,
1825ffd83dbSDimitry Andric MachineBasicBlock *MBB);
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric class SystemZInstrInfo : public SystemZGenInstrInfo {
1860b57cec5SDimitry Andric const SystemZRegisterInfo RI;
1870b57cec5SDimitry Andric SystemZSubtarget &STI;
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;
1900b57cec5SDimitry Andric void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;
1910b57cec5SDimitry Andric void expandRIPseudo(MachineInstr &MI, unsigned LowOpcode, unsigned HighOpcode,
1920b57cec5SDimitry Andric bool ConvertHigh) const;
1930b57cec5SDimitry Andric void expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,
1940b57cec5SDimitry Andric unsigned LowOpcodeK, unsigned HighOpcode) const;
1950b57cec5SDimitry Andric void expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode,
1960b57cec5SDimitry Andric unsigned HighOpcode) const;
1970b57cec5SDimitry Andric void expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode,
1980b57cec5SDimitry Andric unsigned HighOpcode) const;
1990b57cec5SDimitry Andric void expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,
2000b57cec5SDimitry Andric unsigned Size) const;
2010b57cec5SDimitry Andric void expandLoadStackGuard(MachineInstr *MI) const;
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric MachineInstrBuilder
2040b57cec5SDimitry Andric emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
2050b57cec5SDimitry Andric const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
2060b57cec5SDimitry Andric unsigned LowLowOpcode, unsigned Size, bool KillSrc,
2070b57cec5SDimitry Andric bool UndefSrc) const;
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andric virtual void anchor();
2100b57cec5SDimitry Andric
2110b57cec5SDimitry Andric protected:
2120b57cec5SDimitry Andric /// Commutes the operands in the given instruction by changing the operands
2130b57cec5SDimitry Andric /// order and/or changing the instruction's opcode and/or the immediate value
2140b57cec5SDimitry Andric /// operand.
2150b57cec5SDimitry Andric ///
2160b57cec5SDimitry Andric /// The arguments 'CommuteOpIdx1' and 'CommuteOpIdx2' specify the operands
2170b57cec5SDimitry Andric /// to be commuted.
2180b57cec5SDimitry Andric ///
2190b57cec5SDimitry Andric /// Do not call this method for a non-commutable instruction or
2200b57cec5SDimitry Andric /// non-commutable operands.
2210b57cec5SDimitry Andric /// Even though the instruction is commutable, the method may still
2220b57cec5SDimitry Andric /// fail to commute the operands, null pointer is returned in such cases.
2230b57cec5SDimitry Andric MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
2240b57cec5SDimitry Andric unsigned CommuteOpIdx1,
2250b57cec5SDimitry Andric unsigned CommuteOpIdx2) const override;
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric public:
2280b57cec5SDimitry Andric explicit SystemZInstrInfo(SystemZSubtarget &STI);
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric // Override TargetInstrInfo.
2310b57cec5SDimitry Andric unsigned isLoadFromStackSlot(const MachineInstr &MI,
2320b57cec5SDimitry Andric int &FrameIndex) const override;
2330b57cec5SDimitry Andric unsigned isStoreToStackSlot(const MachineInstr &MI,
2340b57cec5SDimitry Andric int &FrameIndex) const override;
2350b57cec5SDimitry Andric bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex,
2360b57cec5SDimitry Andric int &SrcFrameIndex) const override;
2370b57cec5SDimitry Andric bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
2380b57cec5SDimitry Andric MachineBasicBlock *&FBB,
2390b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond,
2400b57cec5SDimitry Andric bool AllowModify) const override;
2410b57cec5SDimitry Andric unsigned removeBranch(MachineBasicBlock &MBB,
2420b57cec5SDimitry Andric int *BytesRemoved = nullptr) const override;
2430b57cec5SDimitry Andric unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
2440b57cec5SDimitry Andric MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
2450b57cec5SDimitry Andric const DebugLoc &DL,
2460b57cec5SDimitry Andric int *BytesAdded = nullptr) const override;
2475ffd83dbSDimitry Andric bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
248349cc55cSDimitry Andric Register &SrcReg2, int64_t &Mask,
249349cc55cSDimitry Andric int64_t &Value) const override;
2500b57cec5SDimitry Andric bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond,
2515ffd83dbSDimitry Andric Register, Register, Register, int &, int &,
2525ffd83dbSDimitry Andric int &) const override;
2530b57cec5SDimitry Andric void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
2545ffd83dbSDimitry Andric const DebugLoc &DL, Register DstReg,
2555ffd83dbSDimitry Andric ArrayRef<MachineOperand> Cond, Register TrueReg,
2565ffd83dbSDimitry Andric Register FalseReg) const override;
2575ffd83dbSDimitry Andric bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,
2580b57cec5SDimitry Andric MachineRegisterInfo *MRI) const override;
2590b57cec5SDimitry Andric bool isPredicable(const MachineInstr &MI) const override;
2600b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
2610b57cec5SDimitry Andric unsigned ExtraPredCycles,
2620b57cec5SDimitry Andric BranchProbability Probability) const override;
2630b57cec5SDimitry Andric bool isProfitableToIfCvt(MachineBasicBlock &TMBB,
2640b57cec5SDimitry Andric unsigned NumCyclesT, unsigned ExtraPredCyclesT,
2650b57cec5SDimitry Andric MachineBasicBlock &FMBB,
2660b57cec5SDimitry Andric unsigned NumCyclesF, unsigned ExtraPredCyclesF,
2670b57cec5SDimitry Andric BranchProbability Probability) const override;
2680b57cec5SDimitry Andric bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
2690b57cec5SDimitry Andric BranchProbability Probability) const override;
2700b57cec5SDimitry Andric bool PredicateInstruction(MachineInstr &MI,
2710b57cec5SDimitry Andric ArrayRef<MachineOperand> Pred) const override;
2720b57cec5SDimitry Andric void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
273480093f4SDimitry Andric const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
2740b57cec5SDimitry Andric bool KillSrc) const override;
2750b57cec5SDimitry Andric void storeRegToStackSlot(MachineBasicBlock &MBB,
276bdd1243dSDimitry Andric MachineBasicBlock::iterator MBBI, Register SrcReg,
277bdd1243dSDimitry Andric bool isKill, int FrameIndex,
2780b57cec5SDimitry Andric const TargetRegisterClass *RC,
279bdd1243dSDimitry Andric const TargetRegisterInfo *TRI,
280bdd1243dSDimitry Andric Register VReg) const override;
2810b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB,
282bdd1243dSDimitry Andric MachineBasicBlock::iterator MBBI, Register DestReg,
283bdd1243dSDimitry Andric int FrameIdx, const TargetRegisterClass *RC,
284bdd1243dSDimitry Andric const TargetRegisterInfo *TRI,
285bdd1243dSDimitry Andric Register VReg) const override;
286349cc55cSDimitry Andric MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,
287349cc55cSDimitry Andric LiveIntervals *LIS) const override;
2880b57cec5SDimitry Andric MachineInstr *
2890b57cec5SDimitry Andric foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,
2900b57cec5SDimitry Andric ArrayRef<unsigned> Ops,
2910b57cec5SDimitry Andric MachineBasicBlock::iterator InsertPt, int FrameIndex,
2920b57cec5SDimitry Andric LiveIntervals *LIS = nullptr,
2930b57cec5SDimitry Andric VirtRegMap *VRM = nullptr) const override;
2940b57cec5SDimitry Andric MachineInstr *foldMemoryOperandImpl(
2950b57cec5SDimitry Andric MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,
2960b57cec5SDimitry Andric MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,
2970b57cec5SDimitry Andric LiveIntervals *LIS = nullptr) const override;
2980b57cec5SDimitry Andric bool expandPostRAPseudo(MachineInstr &MBBI) const override;
2990b57cec5SDimitry Andric bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
3000b57cec5SDimitry Andric override;
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric // Return the SystemZRegisterInfo, which this class owns.
getRegisterInfo()3030b57cec5SDimitry Andric const SystemZRegisterInfo &getRegisterInfo() const { return RI; }
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric // Return the size in bytes of MI.
3060b57cec5SDimitry Andric unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andric // Return true if MI is a conditional or unconditional branch.
3090b57cec5SDimitry Andric // When returning true, set Cond to the mask of condition-code
3100b57cec5SDimitry Andric // values on which the instruction will branch, and set Target
3110b57cec5SDimitry Andric // to the operand that contains the branch target. This target
3120b57cec5SDimitry Andric // can be a register or a basic block.
3130b57cec5SDimitry Andric SystemZII::Branch getBranchInfo(const MachineInstr &MI) const;
3140b57cec5SDimitry Andric
3150b57cec5SDimitry Andric // Get the load and store opcodes for a given register class.
3160b57cec5SDimitry Andric void getLoadStoreOpcodes(const TargetRegisterClass *RC,
3170b57cec5SDimitry Andric unsigned &LoadOpcode, unsigned &StoreOpcode) const;
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric // Opcode is the opcode of an instruction that has an address operand,
3200b57cec5SDimitry Andric // and the caller wants to perform that instruction's operation on an
3210b57cec5SDimitry Andric // address that has displacement Offset. Return the opcode of a suitable
3220b57cec5SDimitry Andric // instruction (which might be Opcode itself) or 0 if no such instruction
32381ad6265SDimitry Andric // exists. MI may be passed in order to allow examination of physical
32481ad6265SDimitry Andric // register operands (i.e. if a VR32/64 reg ended up as an FP or Vector reg).
32581ad6265SDimitry Andric unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset,
32681ad6265SDimitry Andric const MachineInstr *MI = nullptr) const;
3270b57cec5SDimitry Andric
3281fd87a68SDimitry Andric // Return true if Opcode has a mapping in 12 <-> 20 bit displacements.
3291fd87a68SDimitry Andric bool hasDisplacementPairInsn(unsigned Opcode) const;
3301fd87a68SDimitry Andric
3310b57cec5SDimitry Andric // If Opcode is a load instruction that has a LOAD AND TEST form,
3320b57cec5SDimitry Andric // return the opcode for the testing form, otherwise return 0.
3330b57cec5SDimitry Andric unsigned getLoadAndTest(unsigned Opcode) const;
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric // Return true if ROTATE AND ... SELECTED BITS can be used to select bits
3360b57cec5SDimitry Andric // Mask of the R2 operand, given that only the low BitSize bits of Mask are
3370b57cec5SDimitry Andric // significant. Set Start and End to the I3 and I4 operands if so.
3380b57cec5SDimitry Andric bool isRxSBGMask(uint64_t Mask, unsigned BitSize,
3390b57cec5SDimitry Andric unsigned &Start, unsigned &End) const;
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andric // If Opcode is a COMPARE opcode for which an associated fused COMPARE AND *
3420b57cec5SDimitry Andric // operation exists, return the opcode for the latter, otherwise return 0.
3430b57cec5SDimitry Andric // MI, if nonnull, is the compare instruction.
3440b57cec5SDimitry Andric unsigned getFusedCompare(unsigned Opcode,
3450b57cec5SDimitry Andric SystemZII::FusedCompareType Type,
3460b57cec5SDimitry Andric const MachineInstr *MI = nullptr) const;
3470b57cec5SDimitry Andric
3485ffd83dbSDimitry Andric // Try to find all CC users of the compare instruction (MBBI) and update
3495ffd83dbSDimitry Andric // all of them to maintain equivalent behavior after swapping the compare
3505ffd83dbSDimitry Andric // operands. Return false if not all users can be conclusively found and
3515ffd83dbSDimitry Andric // handled. The compare instruction is *not* changed.
3525ffd83dbSDimitry Andric bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const;
3535ffd83dbSDimitry Andric
3540b57cec5SDimitry Andric // If Opcode is a LOAD opcode for with an associated LOAD AND TRAP
3550b57cec5SDimitry Andric // operation exists, returh the opcode for the latter, otherwise return 0.
3560b57cec5SDimitry Andric unsigned getLoadAndTrap(unsigned Opcode) const;
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric // Emit code before MBBI in MI to move immediate value Value into
3590b57cec5SDimitry Andric // physical register Reg.
3600b57cec5SDimitry Andric void loadImmediate(MachineBasicBlock &MBB,
3610b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI,
3620b57cec5SDimitry Andric unsigned Reg, uint64_t Value) const;
3630b57cec5SDimitry Andric
364480093f4SDimitry Andric // Perform target specific instruction verification.
365480093f4SDimitry Andric bool verifyInstruction(const MachineInstr &MI,
366480093f4SDimitry Andric StringRef &ErrInfo) const override;
367480093f4SDimitry Andric
3680b57cec5SDimitry Andric // Sometimes, it is possible for the target to tell, even without
3690b57cec5SDimitry Andric // aliasing information, that two MIs access different memory
3700b57cec5SDimitry Andric // addresses. This function returns true if two MIs access different
3710b57cec5SDimitry Andric // memory addresses and false otherwise.
3720b57cec5SDimitry Andric bool
3730b57cec5SDimitry Andric areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
3748bcb0991SDimitry Andric const MachineInstr &MIb) const override;
3750b57cec5SDimitry Andric };
3760b57cec5SDimitry Andric
3770b57cec5SDimitry Andric } // end namespace llvm
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H
380