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