brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.1 KiB · 9fadf7b Raw
400 lines · c
1//===-- SystemZInstrInfo.h - SystemZ instruction information ----*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the SystemZ implementation of the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H14#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H15 16#include "SystemZ.h"17#include "SystemZRegisterInfo.h"18#include "llvm/ADT/ArrayRef.h"19#include "llvm/CodeGen/MachineBasicBlock.h"20#include "llvm/CodeGen/MachineFunction.h"21#include "llvm/CodeGen/MachineInstrBuilder.h"22#include "llvm/CodeGen/TargetInstrInfo.h"23#include <cstdint>24 25#define GET_INSTRINFO_HEADER26#include "SystemZGenInstrInfo.inc"27 28namespace llvm {29 30class SystemZSubtarget;31 32namespace SystemZII {33 34enum {35  // See comments in SystemZInstrFormats.td.36  SimpleBDXLoad          = (1 << 0),37  SimpleBDXStore         = (1 << 1),38  Has20BitOffset         = (1 << 2),39  HasIndex               = (1 << 3),40  Is128Bit               = (1 << 4),41  AccessSizeMask         = (31 << 5),42  AccessSizeShift        = 5,43  CCValuesMask           = (15 << 10),44  CCValuesShift          = 10,45  CompareZeroCCMaskMask  = (15 << 14),46  CompareZeroCCMaskShift = 14,47  CCMaskFirst            = (1 << 18),48  CCMaskLast             = (1 << 19),49  IsLogical              = (1 << 20),50  CCIfNoSignedWrap       = (1 << 21)51};52 53static inline unsigned getAccessSize(unsigned int Flags) {54  return (Flags & AccessSizeMask) >> AccessSizeShift;55}56 57static inline unsigned getCCValues(unsigned int Flags) {58  return (Flags & CCValuesMask) >> CCValuesShift;59}60 61static inline unsigned getCompareZeroCCMask(unsigned int Flags) {62  return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;63}64 65// SystemZ MachineOperand target flags.66enum {67  // Masks out the bits for the access model.68  MO_SYMBOL_MODIFIER = (3 << 0),69 70  // @GOT (aka @GOTENT)71  MO_GOT = (1 << 0),72 73  // @INDNTPOFF74  MO_INDNTPOFF = (2 << 0),75 76  // z/OS XPLink specific: classifies the types of77  // accesses to the ADA (Associated Data Area).78  MO_ADA_DATA_SYMBOL_ADDR = (1 << 2),79  MO_ADA_INDIRECT_FUNC_DESC = (2 << 2),80  MO_ADA_DIRECT_FUNC_DESC = (3 << 2),81};82 83// Classifies a branch.84enum BranchType {85  // An instruction that branches on the current value of CC.86  BranchNormal,87 88  // An instruction that peforms a 32-bit signed comparison and branches89  // on the result.90  BranchC,91 92  // An instruction that peforms a 32-bit unsigned comparison and branches93  // on the result.94  BranchCL,95 96  // An instruction that peforms a 64-bit signed comparison and branches97  // on the result.98  BranchCG,99 100  // An instruction that peforms a 64-bit unsigned comparison and branches101  // on the result.102  BranchCLG,103 104  // An instruction that decrements a 32-bit register and branches if105  // the result is nonzero.106  BranchCT,107 108  // An instruction that decrements a 64-bit register and branches if109  // the result is nonzero.110  BranchCTG,111 112  // An instruction representing an asm goto statement.113  AsmGoto114};115 116// Information about a branch instruction.117class Branch {118  // The target of the branch. In case of INLINEASM_BR, this is nullptr.119  const MachineOperand *Target;120 121public:122  // The type of the branch.123  BranchType Type;124 125  // CCMASK_<N> is set if CC might be equal to N.126  unsigned CCValid;127 128  // CCMASK_<N> is set if the branch should be taken when CC == N.129  unsigned CCMask;130 131  Branch(BranchType type, unsigned ccValid, unsigned ccMask,132         const MachineOperand *target)133    : Target(target), Type(type), CCValid(ccValid), CCMask(ccMask) {}134 135  bool isIndirect() { return Target != nullptr && Target->isReg(); }136  bool hasMBBTarget() { return Target != nullptr && Target->isMBB(); }137  MachineBasicBlock *getMBBTarget() {138    return hasMBBTarget() ? Target->getMBB() : nullptr;139  }140};141 142// Kinds of fused compares in compare-and-* instructions.  Together with type143// of the converted compare, this identifies the compare-and-*144// instruction.145enum FusedCompareType {146  // Relative branch - CRJ etc.147  CompareAndBranch,148 149  // Indirect branch, used for return - CRBReturn etc.150  CompareAndReturn,151 152  // Indirect branch, used for sibcall - CRBCall etc.153  CompareAndSibcall,154 155  // Trap156  CompareAndTrap157};158 159} // end namespace SystemZII160 161namespace SystemZ {162int getTwoOperandOpcode(uint16_t Opcode);163int getTargetMemOpcode(uint16_t Opcode);164 165// Return a version of comparison CC mask CCMask in which the LT and GT166// actions are swapped.167unsigned reverseCCMask(unsigned CCMask);168 169// Create a new basic block after MBB.170MachineBasicBlock *emitBlockAfter(MachineBasicBlock *MBB);171// Split MBB after MI and return the new block (the one that contains172// instructions after MI).173MachineBasicBlock *splitBlockAfter(MachineBasicBlock::iterator MI,174                                   MachineBasicBlock *MBB);175// Split MBB before MI and return the new block (the one that contains MI).176MachineBasicBlock *splitBlockBefore(MachineBasicBlock::iterator MI,177                                    MachineBasicBlock *MBB);178}179 180class SystemZInstrInfo : public SystemZGenInstrInfo {181  const SystemZRegisterInfo RI;182  const SystemZSubtarget &STI;183 184  void splitMove(MachineBasicBlock::iterator MI, unsigned NewOpcode) const;185  void splitAdjDynAlloc(MachineBasicBlock::iterator MI) const;186  void expandRIPseudo(MachineInstr &MI, unsigned LowOpcode, unsigned HighOpcode,187                      bool ConvertHigh) const;188  void expandRIEPseudo(MachineInstr &MI, unsigned LowOpcode,189                       unsigned LowOpcodeK, unsigned HighOpcode) const;190  void expandRXYPseudo(MachineInstr &MI, unsigned LowOpcode,191                       unsigned HighOpcode) const;192  void expandLOCPseudo(MachineInstr &MI, unsigned LowOpcode,193                       unsigned HighOpcode) const;194  void expandZExtPseudo(MachineInstr &MI, unsigned LowOpcode,195                        unsigned Size) const;196  void expandLoadStackGuard(MachineInstr *MI) const;197 198  MachineInstrBuilder199  emitGRX32Move(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,200                const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,201                unsigned LowLowOpcode, unsigned Size, bool KillSrc,202                bool UndefSrc) const;203 204  virtual void anchor();205 206protected:207  /// Commutes the operands in the given instruction by changing the operands208  /// order and/or changing the instruction's opcode and/or the immediate value209  /// operand.210  ///211  /// The arguments 'CommuteOpIdx1' and 'CommuteOpIdx2' specify the operands212  /// to be commuted.213  ///214  /// Do not call this method for a non-commutable instruction or215  /// non-commutable operands.216  /// Even though the instruction is commutable, the method may still217  /// fail to commute the operands, null pointer is returned in such cases.218  MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,219                                       unsigned CommuteOpIdx1,220                                       unsigned CommuteOpIdx2) const override;221 222public:223  explicit SystemZInstrInfo(const SystemZSubtarget &STI);224 225  // Override TargetInstrInfo.226  Register isLoadFromStackSlot(const MachineInstr &MI,227                               int &FrameIndex) const override;228  Register isStoreToStackSlot(const MachineInstr &MI,229                              int &FrameIndex) const override;230  Register isLoadFromStackSlotPostFE(const MachineInstr &MI,231                                     int &FrameIndex) const override;232  Register isStoreToStackSlotPostFE(const MachineInstr &MI,233                                    int &FrameIndex) const override;234  bool isStackSlotCopy(const MachineInstr &MI, int &DestFrameIndex,235                       int &SrcFrameIndex) const override;236  bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,237                     MachineBasicBlock *&FBB,238                     SmallVectorImpl<MachineOperand> &Cond,239                     bool AllowModify) const override;240  unsigned removeBranch(MachineBasicBlock &MBB,241                        int *BytesRemoved = nullptr) const override;242  unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,243                        MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,244                        const DebugLoc &DL,245                        int *BytesAdded = nullptr) const override;246  bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,247                      Register &SrcReg2, int64_t &Mask,248                      int64_t &Value) const override;249  bool canInsertSelect(const MachineBasicBlock &, ArrayRef<MachineOperand> Cond,250                       Register, Register, Register, int &, int &,251                       int &) const override;252  void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,253                    const DebugLoc &DL, Register DstReg,254                    ArrayRef<MachineOperand> Cond, Register TrueReg,255                    Register FalseReg) const override;256  bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg,257                     MachineRegisterInfo *MRI) const override;258 259  bool isPredicable(const MachineInstr &MI) const override;260  bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,261                           unsigned ExtraPredCycles,262                           BranchProbability Probability) const override;263  bool isProfitableToIfCvt(MachineBasicBlock &TMBB,264                           unsigned NumCyclesT, unsigned ExtraPredCyclesT,265                           MachineBasicBlock &FMBB,266                           unsigned NumCyclesF, unsigned ExtraPredCyclesF,267                           BranchProbability Probability) const override;268  bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,269                            BranchProbability Probability) const override;270  bool PredicateInstruction(MachineInstr &MI,271                            ArrayRef<MachineOperand> Pred) const override;272  void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,273                   const DebugLoc &DL, Register DestReg, Register SrcReg,274                   bool KillSrc, bool RenamableDest = false,275                   bool RenamableSrc = false) const override;276  void storeRegToStackSlot(277      MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg,278      bool isKill, int FrameIndex, const TargetRegisterClass *RC,279 280      Register VReg,281      MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;282  void loadRegFromStackSlot(283      MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,284      Register DestReg, int FrameIdx, const TargetRegisterClass *RC,285 286      Register VReg,287      MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;288  MachineInstr *convertToThreeAddress(MachineInstr &MI, LiveVariables *LV,289                                      LiveIntervals *LIS) const override;290 291  bool useMachineCombiner() const override { return true; }292  bool isAssociativeAndCommutative(const MachineInstr &Inst,293                                   bool Invert) const override;294  std::optional<unsigned> getInverseOpcode(unsigned Opcode) const override;295 296  MachineInstr *297  foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI,298                        ArrayRef<unsigned> Ops,299                        MachineBasicBlock::iterator InsertPt, int FrameIndex,300                        LiveIntervals *LIS = nullptr,301                        VirtRegMap *VRM = nullptr) const override;302  MachineInstr *foldMemoryOperandImpl(303      MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops,304      MachineBasicBlock::iterator InsertPt, MachineInstr &LoadMI,305      LiveIntervals *LIS = nullptr) const override;306  bool expandPostRAPseudo(MachineInstr &MBBI) const override;307  bool reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const308    override;309 310  // Return the SystemZRegisterInfo, which this class owns.311  const SystemZRegisterInfo &getRegisterInfo() const { return RI; }312 313  // Return the size in bytes of MI.314  unsigned getInstSizeInBytes(const MachineInstr &MI) const override;315 316  // Return true if MI is a conditional or unconditional branch.317  // When returning true, set Cond to the mask of condition-code318  // values on which the instruction will branch, and set Target319  // to the operand that contains the branch target.  This target320  // can be a register or a basic block.321  SystemZII::Branch getBranchInfo(const MachineInstr &MI) const;322 323  // Get the load and store opcodes for a given register class.324  void getLoadStoreOpcodes(const TargetRegisterClass *RC,325                           unsigned &LoadOpcode, unsigned &StoreOpcode) const;326 327  // Opcode is the opcode of an instruction that has an address operand,328  // and the caller wants to perform that instruction's operation on an329  // address that has displacement Offset.  Return the opcode of a suitable330  // instruction (which might be Opcode itself) or 0 if no such instruction331  // exists.  MI may be passed in order to allow examination of physical332  // register operands (i.e. if a VR32/64 reg ended up as an FP or Vector reg).333  unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset,334                              const MachineInstr *MI = nullptr) const;335 336  // Return true if Opcode has a mapping in 12 <-> 20 bit displacements.337  bool hasDisplacementPairInsn(unsigned Opcode) const;338 339  // If Opcode is a load instruction that has a LOAD AND TEST form,340  // return the opcode for the testing form, otherwise return 0.341  unsigned getLoadAndTest(unsigned Opcode) const;342 343  // Return true if ROTATE AND ... SELECTED BITS can be used to select bits344  // Mask of the R2 operand, given that only the low BitSize bits of Mask are345  // significant.  Set Start and End to the I3 and I4 operands if so.346  bool isRxSBGMask(uint64_t Mask, unsigned BitSize,347                   unsigned &Start, unsigned &End) const;348 349  // If Opcode is a COMPARE opcode for which an associated fused COMPARE AND *350  // operation exists, return the opcode for the latter, otherwise return 0.351  // MI, if nonnull, is the compare instruction.352  unsigned getFusedCompare(unsigned Opcode,353                           SystemZII::FusedCompareType Type,354                           const MachineInstr *MI = nullptr) const;355 356  // Try to find all CC users of the compare instruction (MBBI) and update357  // all of them to maintain equivalent behavior after swapping the compare358  // operands. Return false if not all users can be conclusively found and359  // handled. The compare instruction is *not* changed.360  bool prepareCompareSwapOperands(MachineBasicBlock::iterator MBBI) const;361 362  // If Opcode is a LOAD opcode for with an associated LOAD AND TRAP363  // operation exists, returh the opcode for the latter, otherwise return 0.364  unsigned getLoadAndTrap(unsigned Opcode) const;365 366  // Emit code before MBBI in MI to move immediate value Value into367  // physical register Reg.368  void loadImmediate(MachineBasicBlock &MBB,369                     MachineBasicBlock::iterator MBBI,370                     unsigned Reg, uint64_t Value) const;371 372  // Perform target specific instruction verification.373  bool verifyInstruction(const MachineInstr &MI,374                         StringRef &ErrInfo) const override;375 376  // Sometimes, it is possible for the target to tell, even without377  // aliasing information, that two MIs access different memory378  // addresses. This function returns true if two MIs access different379  // memory addresses and false otherwise.380  bool381  areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,382                                  const MachineInstr &MIb) const override;383 384  bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg,385                               int64_t &ImmVal) const override;386 387  std::optional<DestSourcePair>388  isCopyInstrImpl(const MachineInstr &MI) const override;389 390  std::pair<unsigned, unsigned>391  decomposeMachineOperandsTargetFlags(unsigned TF) const override;392 393  ArrayRef<std::pair<unsigned, const char *>>394  getSerializableDirectMachineOperandTargetFlags() const override;395};396 397} // end namespace llvm398 399#endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZINSTRINFO_H400