//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "reginfo"
+#include "PPCRegisterInfo.h"
#include "PPC.h"
+#include "PPCFrameLowering.h"
#include "PPCInstrBuilder.h"
#include "PPCMachineFunctionInfo.h"
-#include "PPCRegisterInfo.h"
-#include "PPCFrameLowering.h"
#include "PPCSubtarget.h"
-#include "llvm/CallingConv.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Type.h"
-#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include <cstdlib>
#define GET_REGINFO_TARGET_DESC
: PPCGenRegisterInfo(ST.isPPC64() ? PPC::LR8 : PPC::LR,
ST.isPPC64() ? 0 : 1,
ST.isPPC64() ? 0 : 1),
- Subtarget(ST), TII(tii) {
+ Subtarget(ST), TII(tii), CRSpillFrameIdx(0) {
ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX;
ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX;
ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX;
ImmToIdxMap[PPC::ADDI8] = PPC::ADD8; ImmToIdxMap[PPC::STD_32] = PPC::STDX_32;
}
+bool
+PPCRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
+ return requiresRegisterScavenging(MF);
+}
+
+
/// getPointerRegClass - Return the register class to use to hold pointers.
/// This is used for addressing modes.
const TargetRegisterClass *
-PPCRegisterInfo::getPointerRegClass(unsigned Kind) const {
+PPCRegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
+ const {
if (Subtarget.isPPC64())
return &PPC::G8RCRegClass;
return &PPC::GPRCRegClass;
}
-const unsigned*
+const uint16_t*
PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
- // 32-bit Darwin calling convention.
- static const unsigned Darwin32_CalleeSavedRegs[] = {
- PPC::R13, PPC::R14, PPC::R15,
- PPC::R16, PPC::R17, PPC::R18, PPC::R19,
- PPC::R20, PPC::R21, PPC::R22, PPC::R23,
- PPC::R24, PPC::R25, PPC::R26, PPC::R27,
- PPC::R28, PPC::R29, PPC::R30, PPC::R31,
-
- PPC::F14, PPC::F15, PPC::F16, PPC::F17,
- PPC::F18, PPC::F19, PPC::F20, PPC::F21,
- PPC::F22, PPC::F23, PPC::F24, PPC::F25,
- PPC::F26, PPC::F27, PPC::F28, PPC::F29,
- PPC::F30, PPC::F31,
-
- PPC::CR2, PPC::CR3, PPC::CR4,
- PPC::V20, PPC::V21, PPC::V22, PPC::V23,
- PPC::V24, PPC::V25, PPC::V26, PPC::V27,
- PPC::V28, PPC::V29, PPC::V30, PPC::V31,
-
- PPC::LR, 0
- };
-
- // 32-bit SVR4 calling convention.
- static const unsigned SVR4_CalleeSavedRegs[] = {
- PPC::R14, PPC::R15,
- PPC::R16, PPC::R17, PPC::R18, PPC::R19,
- PPC::R20, PPC::R21, PPC::R22, PPC::R23,
- PPC::R24, PPC::R25, PPC::R26, PPC::R27,
- PPC::R28, PPC::R29, PPC::R30, PPC::R31,
-
- PPC::F14, PPC::F15, PPC::F16, PPC::F17,
- PPC::F18, PPC::F19, PPC::F20, PPC::F21,
- PPC::F22, PPC::F23, PPC::F24, PPC::F25,
- PPC::F26, PPC::F27, PPC::F28, PPC::F29,
- PPC::F30, PPC::F31,
-
- PPC::CR2, PPC::CR3, PPC::CR4,
-
- PPC::VRSAVE,
-
- PPC::V20, PPC::V21, PPC::V22, PPC::V23,
- PPC::V24, PPC::V25, PPC::V26, PPC::V27,
- PPC::V28, PPC::V29, PPC::V30, PPC::V31,
-
- 0
- };
- // 64-bit Darwin calling convention.
- static const unsigned Darwin64_CalleeSavedRegs[] = {
- PPC::X14, PPC::X15,
- PPC::X16, PPC::X17, PPC::X18, PPC::X19,
- PPC::X20, PPC::X21, PPC::X22, PPC::X23,
- PPC::X24, PPC::X25, PPC::X26, PPC::X27,
- PPC::X28, PPC::X29, PPC::X30, PPC::X31,
-
- PPC::F14, PPC::F15, PPC::F16, PPC::F17,
- PPC::F18, PPC::F19, PPC::F20, PPC::F21,
- PPC::F22, PPC::F23, PPC::F24, PPC::F25,
- PPC::F26, PPC::F27, PPC::F28, PPC::F29,
- PPC::F30, PPC::F31,
-
- PPC::CR2, PPC::CR3, PPC::CR4,
- PPC::V20, PPC::V21, PPC::V22, PPC::V23,
- PPC::V24, PPC::V25, PPC::V26, PPC::V27,
- PPC::V28, PPC::V29, PPC::V30, PPC::V31,
-
- PPC::LR8, 0
- };
-
- // 64-bit SVR4 calling convention.
- static const unsigned SVR4_64_CalleeSavedRegs[] = {
- PPC::X14, PPC::X15,
- PPC::X16, PPC::X17, PPC::X18, PPC::X19,
- PPC::X20, PPC::X21, PPC::X22, PPC::X23,
- PPC::X24, PPC::X25, PPC::X26, PPC::X27,
- PPC::X28, PPC::X29, PPC::X30, PPC::X31,
-
- PPC::F14, PPC::F15, PPC::F16, PPC::F17,
- PPC::F18, PPC::F19, PPC::F20, PPC::F21,
- PPC::F22, PPC::F23, PPC::F24, PPC::F25,
- PPC::F26, PPC::F27, PPC::F28, PPC::F29,
- PPC::F30, PPC::F31,
-
- PPC::CR2, PPC::CR3, PPC::CR4,
+ if (Subtarget.isDarwinABI())
+ return Subtarget.isPPC64() ? CSR_Darwin64_SaveList :
+ CSR_Darwin32_SaveList;
- PPC::VRSAVE,
+ // For 32-bit SVR4, also initialize the frame index associated with
+ // the CR spill slot.
+ if (!Subtarget.isPPC64())
+ CRSpillFrameIdx = 0;
- PPC::V20, PPC::V21, PPC::V22, PPC::V23,
- PPC::V24, PPC::V25, PPC::V26, PPC::V27,
- PPC::V28, PPC::V29, PPC::V30, PPC::V31,
+ return Subtarget.isPPC64() ? CSR_SVR464_SaveList : CSR_SVR432_SaveList;
+}
- 0
- };
-
+const uint32_t*
+PPCRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
if (Subtarget.isDarwinABI())
- return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs :
- Darwin32_CalleeSavedRegs;
+ return Subtarget.isPPC64() ? CSR_Darwin64_RegMask :
+ CSR_Darwin32_RegMask;
- return Subtarget.isPPC64() ? SVR4_64_CalleeSavedRegs : SVR4_CalleeSavedRegs;
+ return Subtarget.isPPC64() ? CSR_SVR464_RegMask : CSR_SVR432_RegMask;
}
BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
}
}
+bool
+PPCRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
+ switch (RC->getID()) {
+ case PPC::G8RCRegClassID:
+ case PPC::GPRCRegClassID:
+ case PPC::F8RCRegClassID:
+ case PPC::F4RCRegClassID:
+ case PPC::VRRCRegClassID:
+ return true;
+ default:
+ return false;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//
// address of new allocated space.
if (LP64) {
if (requiresRegisterScavenging(MF)) // FIXME (64-bit): Use "true" part.
- BuildMI(MBB, II, dl, TII.get(PPC::STDUX))
+ BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1)
.addReg(Reg, RegState::Kill)
- .addReg(PPC::X1, RegState::Define)
+ .addReg(PPC::X1)
.addReg(MI.getOperand(1).getReg());
else
- BuildMI(MBB, II, dl, TII.get(PPC::STDUX))
+ BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1)
.addReg(PPC::X0, RegState::Kill)
- .addReg(PPC::X1, RegState::Define)
+ .addReg(PPC::X1)
.addReg(MI.getOperand(1).getReg());
if (!MI.getOperand(1).isKill())
.addImm(maxCallFrameSize)
.addReg(MI.getOperand(1).getReg(), RegState::ImplicitKill);
} else {
- BuildMI(MBB, II, dl, TII.get(PPC::STWUX))
+ BuildMI(MBB, II, dl, TII.get(PPC::STWUX), PPC::R1)
.addReg(Reg, RegState::Kill)
- .addReg(PPC::R1, RegState::Define)
+ .addReg(PPC::R1)
.addReg(MI.getOperand(1).getReg());
if (!MI.getOperand(1).isKill())
MBB.erase(II);
}
+bool
+PPCRegisterInfo::hasReservedSpillSlot(const MachineFunction &MF,
+ unsigned Reg, int &FrameIdx) const {
+
+ // For the nonvolatile condition registers (CR2, CR3, CR4) in an SVR4
+ // ABI, return true to prevent allocating an additional frame slot.
+ // For 64-bit, the CR save area is at SP+8; the value of FrameIdx = 0
+ // is arbitrary and will be subsequently ignored. For 32-bit, we must
+ // create exactly one stack slot and return its FrameIdx for all
+ // nonvolatiles.
+ if (Subtarget.isSVR4ABI() && PPC::CR2 <= Reg && Reg <= PPC::CR4) {
+ if (Subtarget.isPPC64()) {
+ FrameIdx = 0;
+ } else if (CRSpillFrameIdx) {
+ FrameIdx = CRSpillFrameIdx;
+ } else {
+ MachineFrameInfo *MFI =
+ (const_cast<MachineFunction &>(MF)).getFrameInfo();
+ FrameIdx = MFI->CreateFixedObject((uint64_t)4, (int64_t)-4, true);
+ CRSpillFrameIdx = FrameIdx;
+ }
+ return true;
+ }
+ return false;
+}
+
void
PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
- int SPAdj, RegScavenger *RS) const {
+ int SPAdj, unsigned FIOperandNum,
+ RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected");
// Get the instruction.
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
DebugLoc dl = MI.getDebugLoc();
- // Find out which operand is the frame index.
- unsigned FIOperandNo = 0;
- while (!MI.getOperand(FIOperandNo).isFI()) {
- ++FIOperandNo;
- assert(FIOperandNo != MI.getNumOperands() &&
- "Instr doesn't have FrameIndex operand!");
- }
// Take into account whether it's an add or mem instruction
- unsigned OffsetOperandNo = (FIOperandNo == 2) ? 1 : 2;
+ unsigned OffsetOperandNo = (FIOperandNum == 2) ? 1 : 2;
if (MI.isInlineAsm())
- OffsetOperandNo = FIOperandNo-1;
+ OffsetOperandNo = FIOperandNum-1;
// Get the frame index.
- int FrameIndex = MI.getOperand(FIOperandNo).getIndex();
+ int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
// Get the frame pointer save index. Users of this index are primarily
// DYNALLOC instructions.
// Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
bool is64Bit = Subtarget.isPPC64();
- MI.getOperand(FIOperandNo).ChangeToRegister(TFI->hasFP(MF) ?
+ MI.getOperand(FIOperandNum).ChangeToRegister(TFI->hasFP(MF) ?
(is64Bit ? PPC::X31 : PPC::R31) :
(is64Bit ? PPC::X1 : PPC::R1),
false);
// to Offset to get the correct offset.
// Naked functions have stack size 0, although getStackSize may not reflect that
// because we didn't call all the pieces that compute it for naked functions.
- if (!MF.getFunction()->hasFnAttr(Attribute::Naked))
+ if (!MF.getFunction()->getAttributes().
+ hasAttribute(AttributeSet::FunctionIndex, Attribute::Naked))
Offset += MFI->getStackSize();
// If we can, encode the offset directly into the instruction. If this is a
// clear can be encoded. This is extremely uncommon, because normally you
// only "std" to a stack slot that is at least 4-byte aligned, but it can
// happen in invalid code.
- if (isInt<16>(Offset) && (!isIXAddr || (Offset & 3) == 0)) {
+ if (OpC == PPC::DBG_VALUE || // DBG_VALUE is always Reg+Imm
+ (isInt<16>(Offset) && (!isIXAddr || (Offset & 3) == 0))) {
if (isIXAddr)
Offset >>= 2; // The actual encoded value has the low two bits zero.
MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset);
OperandBase = OffsetOperandNo;
}
- unsigned StackReg = MI.getOperand(FIOperandNo).getReg();
+ unsigned StackReg = MI.getOperand(FIOperandNum).getReg();
MI.getOperand(OperandBase).ChangeToRegister(StackReg, false);
MI.getOperand(OperandBase + 1).ChangeToRegister(SReg, false, false, true);
}