1 //===-- RISCVRegisterInfo.h - RISC-V Register Information Impl --*- 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the RISC-V implementation of the TargetRegisterInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVREGISTERINFO_H 14 #define LLVM_LIB_TARGET_RISCV_RISCVREGISTERINFO_H 15 16 #include "llvm/CodeGen/TargetRegisterInfo.h" 17 #include "llvm/TargetParser/RISCVTargetParser.h" 18 19 #define GET_REGINFO_HEADER 20 #include "RISCVGenRegisterInfo.inc" 21 22 namespace llvm { 23 24 namespace RISCVRI { 25 enum { 26 // The IsVRegClass value of this RegisterClass. 27 IsVRegClassShift = 0, 28 IsVRegClassShiftMask = 0b1 << IsVRegClassShift, 29 // The VLMul value of this RegisterClass. This value is valid iff IsVRegClass 30 // is true. 31 VLMulShift = IsVRegClassShift + 1, 32 VLMulShiftMask = 0b111 << VLMulShift, 33 34 // The NF value of this RegisterClass. This value is valid iff IsVRegClass is 35 // true. 36 NFShift = VLMulShift + 3, 37 NFShiftMask = 0b111 << NFShift, 38 }; 39 40 /// \returns the IsVRegClass for the register class. 41 static inline bool isVRegClass(uint64_t TSFlags) { 42 return (TSFlags & IsVRegClassShiftMask) >> IsVRegClassShift; 43 } 44 45 /// \returns the LMUL for the register class. 46 static inline RISCVII::VLMUL getLMul(uint64_t TSFlags) { 47 return static_cast<RISCVII::VLMUL>((TSFlags & VLMulShiftMask) >> VLMulShift); 48 } 49 50 /// \returns the NF for the register class. 51 static inline unsigned getNF(uint64_t TSFlags) { 52 return static_cast<unsigned>((TSFlags & NFShiftMask) >> NFShift) + 1; 53 } 54 } // namespace RISCVRI 55 56 struct RISCVRegisterInfo : public RISCVGenRegisterInfo { 57 58 RISCVRegisterInfo(unsigned HwMode); 59 60 const uint32_t *getCallPreservedMask(const MachineFunction &MF, 61 CallingConv::ID) const override; 62 63 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 64 65 BitVector getReservedRegs(const MachineFunction &MF) const override; 66 bool isAsmClobberable(const MachineFunction &MF, 67 MCRegister PhysReg) const override; 68 69 const uint32_t *getNoPreservedMask() const override; 70 71 // Update DestReg to have the value SrcReg plus an offset. This is 72 // used during frame layout, and we may need to ensure that if we 73 // split the offset internally that the DestReg is always aligned, 74 // assuming that source reg was. 75 void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, 76 const DebugLoc &DL, Register DestReg, Register SrcReg, 77 StackOffset Offset, MachineInstr::MIFlag Flag, 78 MaybeAlign RequiredAlign) const; 79 80 bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, 81 unsigned FIOperandNum, 82 RegScavenger *RS = nullptr) const override; 83 84 bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override; 85 86 bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 87 88 bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, 89 int64_t Offset) const override; 90 91 Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, 92 int64_t Offset) const override; 93 94 void resolveFrameIndex(MachineInstr &MI, Register BaseReg, 95 int64_t Offset) const override; 96 97 int64_t getFrameIndexInstrOffset(const MachineInstr *MI, 98 int Idx) const override; 99 100 void lowerVSPILL(MachineBasicBlock::iterator II) const; 101 void lowerVRELOAD(MachineBasicBlock::iterator II) const; 102 103 Register getFrameRegister(const MachineFunction &MF) const override; 104 105 StringRef getRegAsmName(MCRegister Reg) const override; 106 107 bool requiresRegisterScavenging(const MachineFunction &MF) const override { 108 return true; 109 } 110 111 bool requiresFrameIndexScavenging(const MachineFunction &MF) const override { 112 return true; 113 } 114 115 const TargetRegisterClass * 116 getPointerRegClass(const MachineFunction &MF, 117 unsigned Kind = 0) const override { 118 return &RISCV::GPRRegClass; 119 } 120 121 const TargetRegisterClass * 122 getLargestLegalSuperClass(const TargetRegisterClass *RC, 123 const MachineFunction &) const override; 124 125 void getOffsetOpcodes(const StackOffset &Offset, 126 SmallVectorImpl<uint64_t> &Ops) const override; 127 128 unsigned getRegisterCostTableIndex(const MachineFunction &MF) const override; 129 130 bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order, 131 SmallVectorImpl<MCPhysReg> &Hints, 132 const MachineFunction &MF, const VirtRegMap *VRM, 133 const LiveRegMatrix *Matrix) const override; 134 135 static bool isVRRegClass(const TargetRegisterClass *RC) { 136 return RISCVRI::isVRegClass(RC->TSFlags) && 137 RISCVRI::getNF(RC->TSFlags) == 1; 138 } 139 140 static bool isVRNRegClass(const TargetRegisterClass *RC) { 141 return RISCVRI::isVRegClass(RC->TSFlags) && RISCVRI::getNF(RC->TSFlags) > 1; 142 } 143 144 static bool isRVVRegClass(const TargetRegisterClass *RC) { 145 return RISCVRI::isVRegClass(RC->TSFlags); 146 } 147 }; 148 } // namespace llvm 149 150 #endif 151