xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCRegisterInfo.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- PPCRegisterInfo.h - PowerPC Register Information Impl ---*- 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 PowerPC implementation of the TargetRegisterInfo
100b57cec5SDimitry Andric // class.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H
150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #define GET_REGINFO_HEADER
210b57cec5SDimitry Andric #include "PPCGenRegisterInfo.inc"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace llvm {
240b57cec5SDimitry Andric class PPCTargetMachine;
250b57cec5SDimitry Andric 
getCRFromCRBit(unsigned SrcReg)260b57cec5SDimitry Andric inline static unsigned getCRFromCRBit(unsigned SrcReg) {
270b57cec5SDimitry Andric   unsigned Reg = 0;
280b57cec5SDimitry Andric   if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||
290b57cec5SDimitry Andric       SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)
300b57cec5SDimitry Andric     Reg = PPC::CR0;
310b57cec5SDimitry Andric   else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||
320b57cec5SDimitry Andric            SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)
330b57cec5SDimitry Andric     Reg = PPC::CR1;
340b57cec5SDimitry Andric   else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||
350b57cec5SDimitry Andric            SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)
360b57cec5SDimitry Andric     Reg = PPC::CR2;
370b57cec5SDimitry Andric   else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||
380b57cec5SDimitry Andric            SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)
390b57cec5SDimitry Andric     Reg = PPC::CR3;
400b57cec5SDimitry Andric   else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||
410b57cec5SDimitry Andric            SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)
420b57cec5SDimitry Andric     Reg = PPC::CR4;
430b57cec5SDimitry Andric   else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||
440b57cec5SDimitry Andric            SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)
450b57cec5SDimitry Andric     Reg = PPC::CR5;
460b57cec5SDimitry Andric   else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||
470b57cec5SDimitry Andric            SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)
480b57cec5SDimitry Andric     Reg = PPC::CR6;
490b57cec5SDimitry Andric   else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||
500b57cec5SDimitry Andric            SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
510b57cec5SDimitry Andric     Reg = PPC::CR7;
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   assert(Reg != 0 && "Invalid CR bit register");
540b57cec5SDimitry Andric   return Reg;
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric class PPCRegisterInfo : public PPCGenRegisterInfo {
580b57cec5SDimitry Andric   DenseMap<unsigned, unsigned> ImmToIdxMap;
590b57cec5SDimitry Andric   const PPCTargetMachine &TM;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric public:
620b57cec5SDimitry Andric   PPCRegisterInfo(const PPCTargetMachine &TM);
630b57cec5SDimitry Andric 
64480093f4SDimitry Andric   /// getMappedIdxOpcForImmOpc - Return the mapped index form load/store opcode
65480093f4SDimitry Andric   /// for a given imm form load/store opcode \p ImmFormOpcode.
66480093f4SDimitry Andric   /// FIXME: move this to PPCInstrInfo class.
getMappedIdxOpcForImmOpc(unsigned ImmOpcode)67480093f4SDimitry Andric   unsigned getMappedIdxOpcForImmOpc(unsigned ImmOpcode) const {
68480093f4SDimitry Andric     if (!ImmToIdxMap.count(ImmOpcode))
69480093f4SDimitry Andric       return PPC::INSTRUCTION_LIST_END;
70480093f4SDimitry Andric     return ImmToIdxMap.find(ImmOpcode)->second;
71480093f4SDimitry Andric   }
72480093f4SDimitry Andric 
730b57cec5SDimitry Andric   /// getPointerRegClass - Return the register class to use to hold pointers.
740b57cec5SDimitry Andric   /// This is used for addressing modes.
750b57cec5SDimitry Andric   const TargetRegisterClass *
760b57cec5SDimitry Andric   getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
790b57cec5SDimitry Andric                                MachineFunction &MF) const override;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   const TargetRegisterClass *
820b57cec5SDimitry Andric   getLargestLegalSuperClass(const TargetRegisterClass *RC,
830b57cec5SDimitry Andric                             const MachineFunction &MF) const override;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   /// Code Generation virtual methods...
860b57cec5SDimitry Andric   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
870b57cec5SDimitry Andric   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
880b57cec5SDimitry Andric                                        CallingConv::ID CC) const override;
890b57cec5SDimitry Andric   const uint32_t *getNoPreservedMask() const override;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   void adjustStackMapLiveOutMask(uint32_t *Mask) const override;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   BitVector getReservedRegs(const MachineFunction &MF) const override;
9404eeddc0SDimitry Andric   bool isAsmClobberable(const MachineFunction &MF,
9504eeddc0SDimitry Andric                         MCRegister PhysReg) const override;
965ffd83dbSDimitry Andric   bool isCallerPreservedPhysReg(MCRegister PhysReg,
975ffd83dbSDimitry Andric                                 const MachineFunction &MF) const override;
980b57cec5SDimitry Andric 
99fe6060f1SDimitry Andric   // Provide hints to the register allocator for allocating subregisters
100fe6060f1SDimitry Andric   // of primed and unprimed accumulators. For example, if accumulator
101fe6060f1SDimitry Andric   // ACC5 is assigned, we also want to assign UACC5 to the input.
102fe6060f1SDimitry Andric   // Similarly if UACC5 is assigned, we want to assign VSRp10, VSRp11
103fe6060f1SDimitry Andric   // to its inputs.
104fe6060f1SDimitry Andric   bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
105fe6060f1SDimitry Andric                              SmallVectorImpl<MCPhysReg> &Hints,
106fe6060f1SDimitry Andric                              const MachineFunction &MF, const VirtRegMap *VRM,
107fe6060f1SDimitry Andric                              const LiveRegMatrix *Matrix) const override;
108fe6060f1SDimitry Andric 
1090b57cec5SDimitry Andric   /// We require the register scavenger.
requiresRegisterScavenging(const MachineFunction & MF)1100b57cec5SDimitry Andric   bool requiresRegisterScavenging(const MachineFunction &MF) const override {
1110b57cec5SDimitry Andric     return true;
1120b57cec5SDimitry Andric   }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
1150b57cec5SDimitry Andric 
116fe6060f1SDimitry Andric   bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   void lowerDynamicAlloc(MachineBasicBlock::iterator II) const;
1190b57cec5SDimitry Andric   void lowerDynamicAreaOffset(MachineBasicBlock::iterator II) const;
1205ffd83dbSDimitry Andric   void prepareDynamicAlloca(MachineBasicBlock::iterator II,
1215ffd83dbSDimitry Andric                             Register &NegSizeReg, bool &KillNegSizeReg,
1225ffd83dbSDimitry Andric                             Register &FramePointer) const;
1235ffd83dbSDimitry Andric   void lowerPrepareProbedAlloca(MachineBasicBlock::iterator II) const;
1240b57cec5SDimitry Andric   void lowerCRSpilling(MachineBasicBlock::iterator II,
1250b57cec5SDimitry Andric                        unsigned FrameIndex) const;
1260b57cec5SDimitry Andric   void lowerCRRestore(MachineBasicBlock::iterator II,
1270b57cec5SDimitry Andric                       unsigned FrameIndex) const;
1280b57cec5SDimitry Andric   void lowerCRBitSpilling(MachineBasicBlock::iterator II,
1290b57cec5SDimitry Andric                           unsigned FrameIndex) const;
1300b57cec5SDimitry Andric   void lowerCRBitRestore(MachineBasicBlock::iterator II,
1310b57cec5SDimitry Andric                          unsigned FrameIndex) const;
132e8d8bef9SDimitry Andric 
13381ad6265SDimitry Andric   void lowerOctWordSpilling(MachineBasicBlock::iterator II,
13481ad6265SDimitry Andric                             unsigned FrameIndex) const;
135e8d8bef9SDimitry Andric   void lowerACCSpilling(MachineBasicBlock::iterator II,
1360b57cec5SDimitry Andric                         unsigned FrameIndex) const;
137e8d8bef9SDimitry Andric   void lowerACCRestore(MachineBasicBlock::iterator II,
1380b57cec5SDimitry Andric                        unsigned FrameIndex) const;
1390b57cec5SDimitry Andric 
140*bdd1243dSDimitry Andric   void lowerWACCSpilling(MachineBasicBlock::iterator II,
141*bdd1243dSDimitry Andric                          unsigned FrameIndex) const;
142*bdd1243dSDimitry Andric   void lowerWACCRestore(MachineBasicBlock::iterator II,
143*bdd1243dSDimitry Andric                         unsigned FrameIndex) const;
144*bdd1243dSDimitry Andric 
145fe6060f1SDimitry Andric   void lowerQuadwordSpilling(MachineBasicBlock::iterator II,
146fe6060f1SDimitry Andric                              unsigned FrameIndex) const;
147fe6060f1SDimitry Andric   void lowerQuadwordRestore(MachineBasicBlock::iterator II,
148fe6060f1SDimitry Andric                             unsigned FrameIndex) const;
149fe6060f1SDimitry Andric 
150e8d8bef9SDimitry Andric   static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg,
151e8d8bef9SDimitry Andric                               MCRegister SrcReg);
152e8d8bef9SDimitry Andric 
1535ffd83dbSDimitry Andric   bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg,
1540b57cec5SDimitry Andric                             int &FrameIdx) const override;
155*bdd1243dSDimitry Andric   bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
1560b57cec5SDimitry Andric                            unsigned FIOperandNum,
1570b57cec5SDimitry Andric                            RegScavenger *RS = nullptr) const override;
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   // Support for virtual base registers.
1600b57cec5SDimitry Andric   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
161e8d8bef9SDimitry Andric   Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
1620b57cec5SDimitry Andric                                         int64_t Offset) const override;
1635ffd83dbSDimitry Andric   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
1640b57cec5SDimitry Andric                          int64_t Offset) const override;
1655ffd83dbSDimitry Andric   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
1660b57cec5SDimitry Andric                           int64_t Offset) const override;
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   // Debug information queries.
1690b57cec5SDimitry Andric   Register getFrameRegister(const MachineFunction &MF) const override;
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric   // Base pointer (stack realignment) support.
1720b57cec5SDimitry Andric   Register getBaseRegister(const MachineFunction &MF) const;
1730b57cec5SDimitry Andric   bool hasBasePointer(const MachineFunction &MF) const;
1740b57cec5SDimitry Andric 
isNonallocatableRegisterCalleeSave(MCRegister Reg)17504eeddc0SDimitry Andric   bool isNonallocatableRegisterCalleeSave(MCRegister Reg) const override {
17604eeddc0SDimitry Andric     return Reg == PPC::LR || Reg == PPC::LR8;
17704eeddc0SDimitry Andric   }
1780b57cec5SDimitry Andric };
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric } // end namespace llvm
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric #endif
183