| 1 | //===-- PPCRegisterInfo.h - PowerPC 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 PowerPC implementation of the TargetRegisterInfo |
| 10 | // class. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H |
| 15 | #define LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H |
| 16 | |
| 17 | #include "MCTargetDesc/PPCMCTargetDesc.h" |
| 18 | #include "llvm/ADT/DenseMap.h" |
| 19 | |
| 20 | #define |
| 21 | #include "PPCGenRegisterInfo.inc" |
| 22 | |
| 23 | namespace llvm { |
| 24 | class PPCTargetMachine; |
| 25 | |
| 26 | inline static unsigned getCRFromCRBit(unsigned SrcReg) { |
| 27 | unsigned Reg = 0; |
| 28 | if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT || |
| 29 | SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN) |
| 30 | Reg = PPC::CR0; |
| 31 | else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT || |
| 32 | SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN) |
| 33 | Reg = PPC::CR1; |
| 34 | else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT || |
| 35 | SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN) |
| 36 | Reg = PPC::CR2; |
| 37 | else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT || |
| 38 | SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN) |
| 39 | Reg = PPC::CR3; |
| 40 | else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT || |
| 41 | SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN) |
| 42 | Reg = PPC::CR4; |
| 43 | else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT || |
| 44 | SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN) |
| 45 | Reg = PPC::CR5; |
| 46 | else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT || |
| 47 | SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN) |
| 48 | Reg = PPC::CR6; |
| 49 | else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT || |
| 50 | SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN) |
| 51 | Reg = PPC::CR7; |
| 52 | |
| 53 | assert(Reg != 0 && "Invalid CR bit register" ); |
| 54 | return Reg; |
| 55 | } |
| 56 | |
| 57 | class PPCRegisterInfo : public PPCGenRegisterInfo { |
| 58 | DenseMap<unsigned, unsigned> ImmToIdxMap; |
| 59 | const PPCTargetMachine &TM; |
| 60 | |
| 61 | void spillRegPair(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, |
| 62 | DebugLoc DL, const TargetInstrInfo &TII, |
| 63 | unsigned FrameIndex, bool IsLittleEndian, bool IsKilled, |
| 64 | Register Reg, int Offset) const; |
| 65 | |
| 66 | public: |
| 67 | PPCRegisterInfo(const PPCTargetMachine &TM); |
| 68 | |
| 69 | /// getMappedIdxOpcForImmOpc - Return the mapped index form load/store opcode |
| 70 | /// for a given imm form load/store opcode \p ImmFormOpcode. |
| 71 | /// FIXME: move this to PPCInstrInfo class. |
| 72 | unsigned getMappedIdxOpcForImmOpc(unsigned ImmOpcode) const { |
| 73 | auto It = ImmToIdxMap.find(Val: ImmOpcode); |
| 74 | if (It == ImmToIdxMap.end()) |
| 75 | return PPC::INSTRUCTION_LIST_END; |
| 76 | return It->second; |
| 77 | } |
| 78 | |
| 79 | /// getPointerRegClass - Return the register class to use to hold pointers. |
| 80 | /// This is used for addressing modes. |
| 81 | const TargetRegisterClass * |
| 82 | getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override; |
| 83 | |
| 84 | const TargetRegisterClass * |
| 85 | getCrossCopyRegClass(const TargetRegisterClass *RC) const override; |
| 86 | |
| 87 | unsigned getRegPressureLimit(const TargetRegisterClass *RC, |
| 88 | MachineFunction &MF) const override; |
| 89 | |
| 90 | const TargetRegisterClass * |
| 91 | getLargestLegalSuperClass(const TargetRegisterClass *RC, |
| 92 | const MachineFunction &MF) const override; |
| 93 | |
| 94 | /// Code Generation virtual methods... |
| 95 | const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; |
| 96 | const uint32_t *getCallPreservedMask(const MachineFunction &MF, |
| 97 | CallingConv::ID CC) const override; |
| 98 | const uint32_t *getNoPreservedMask() const override; |
| 99 | |
| 100 | void adjustStackMapLiveOutMask(uint32_t *Mask) const override; |
| 101 | |
| 102 | BitVector getReservedRegs(const MachineFunction &MF) const override; |
| 103 | bool isAsmClobberable(const MachineFunction &MF, |
| 104 | MCRegister PhysReg) const override; |
| 105 | bool isCallerPreservedPhysReg(MCRegister PhysReg, |
| 106 | const MachineFunction &MF) const override; |
| 107 | |
| 108 | // Provide hints to the register allocator for allocating subregisters |
| 109 | // of primed and unprimed accumulators. For example, if accumulator |
| 110 | // ACC5 is assigned, we also want to assign UACC5 to the input. |
| 111 | // Similarly if UACC5 is assigned, we want to assign VSRp10, VSRp11 |
| 112 | // to its inputs. |
| 113 | bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order, |
| 114 | SmallVectorImpl<MCPhysReg> &Hints, |
| 115 | const MachineFunction &MF, const VirtRegMap *VRM, |
| 116 | const LiveRegMatrix *Matrix) const override; |
| 117 | |
| 118 | /// We require the register scavenger. |
| 119 | bool requiresRegisterScavenging(const MachineFunction &MF) const override { |
| 120 | return true; |
| 121 | } |
| 122 | |
| 123 | bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; |
| 124 | |
| 125 | bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override; |
| 126 | |
| 127 | void lowerDynamicAlloc(MachineBasicBlock::iterator II) const; |
| 128 | void lowerDynamicAreaOffset(MachineBasicBlock::iterator II) const; |
| 129 | void prepareDynamicAlloca(MachineBasicBlock::iterator II, |
| 130 | Register &NegSizeReg, bool &KillNegSizeReg, |
| 131 | Register &FramePointer) const; |
| 132 | void lowerPrepareProbedAlloca(MachineBasicBlock::iterator II) const; |
| 133 | void lowerCRSpilling(MachineBasicBlock::iterator II, |
| 134 | unsigned FrameIndex) const; |
| 135 | void lowerCRRestore(MachineBasicBlock::iterator II, |
| 136 | unsigned FrameIndex) const; |
| 137 | void lowerCRBitSpilling(MachineBasicBlock::iterator II, |
| 138 | unsigned FrameIndex) const; |
| 139 | void lowerCRBitRestore(MachineBasicBlock::iterator II, |
| 140 | unsigned FrameIndex) const; |
| 141 | |
| 142 | void lowerOctWordSpilling(MachineBasicBlock::iterator II, |
| 143 | unsigned FrameIndex) const; |
| 144 | void lowerACCSpilling(MachineBasicBlock::iterator II, |
| 145 | unsigned FrameIndex) const; |
| 146 | void lowerACCRestore(MachineBasicBlock::iterator II, |
| 147 | unsigned FrameIndex) const; |
| 148 | |
| 149 | void lowerWACCSpilling(MachineBasicBlock::iterator II, |
| 150 | unsigned FrameIndex) const; |
| 151 | void lowerWACCRestore(MachineBasicBlock::iterator II, |
| 152 | unsigned FrameIndex) const; |
| 153 | |
| 154 | void lowerQuadwordSpilling(MachineBasicBlock::iterator II, |
| 155 | unsigned FrameIndex) const; |
| 156 | void lowerQuadwordRestore(MachineBasicBlock::iterator II, |
| 157 | unsigned FrameIndex) const; |
| 158 | |
| 159 | void lowerDMRSpilling(MachineBasicBlock::iterator II, |
| 160 | unsigned FrameIndex) const; |
| 161 | void lowerDMRRestore(MachineBasicBlock::iterator II, |
| 162 | unsigned FrameIndex) const; |
| 163 | |
| 164 | static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg, |
| 165 | MCRegister SrcReg); |
| 166 | |
| 167 | bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg, |
| 168 | int &FrameIdx) const override; |
| 169 | bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, |
| 170 | unsigned FIOperandNum, |
| 171 | RegScavenger *RS = nullptr) const override; |
| 172 | |
| 173 | // Support for virtual base registers. |
| 174 | bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; |
| 175 | Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, |
| 176 | int64_t Offset) const override; |
| 177 | void resolveFrameIndex(MachineInstr &MI, Register BaseReg, |
| 178 | int64_t Offset) const override; |
| 179 | bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, |
| 180 | int64_t Offset) const override; |
| 181 | |
| 182 | // Debug information queries. |
| 183 | Register getFrameRegister(const MachineFunction &MF) const override; |
| 184 | |
| 185 | // Base pointer (stack realignment) support. |
| 186 | Register getBaseRegister(const MachineFunction &MF) const; |
| 187 | bool hasBasePointer(const MachineFunction &MF) const; |
| 188 | |
| 189 | bool isNonallocatableRegisterCalleeSave(MCRegister Reg) const override { |
| 190 | return Reg == PPC::LR || Reg == PPC::LR8; |
| 191 | } |
| 192 | |
| 193 | bool isVirtualFrameRegister(MCRegister Reg) const override { |
| 194 | return Reg == PPC::FP || Reg == PPC::FP8; |
| 195 | } |
| 196 | }; |
| 197 | |
| 198 | } // end namespace llvm |
| 199 | |
| 200 | #endif |
| 201 | |