mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-27 05:53:07 +01:00
4c1f3c24db
into their new header subdirectory: include/llvm/IR. This matches the directory structure of lib, and begins to correct a long standing point of file layout clutter in LLVM. There are still more header files to move here, but I wanted to handle them in separate commits to make tracking what files make sense at each layer easier. The only really questionable files here are the target intrinsic tablegen files. But that's a battle I'd rather not fight today. I've updated both CMake and Makefile build systems (I think, and my tests think, but I may have missed something). I've also re-sorted the includes throughout the project. I'll be committing updates to Clang, DragonEgg, and Polly momentarily. llvm-svn: 171366
228 lines
7.7 KiB
C++
228 lines
7.7 KiB
C++
//===-- MSP430RegisterInfo.cpp - MSP430 Register Information --------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains the MSP430 implementation of the TargetRegisterInfo class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "msp430-reg-info"
|
|
|
|
#include "MSP430RegisterInfo.h"
|
|
#include "MSP430.h"
|
|
#include "MSP430MachineFunctionInfo.h"
|
|
#include "MSP430TargetMachine.h"
|
|
#include "llvm/ADT/BitVector.h"
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/IR/Function.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include "llvm/Target/TargetOptions.h"
|
|
|
|
#define GET_REGINFO_TARGET_DESC
|
|
#include "MSP430GenRegisterInfo.inc"
|
|
|
|
using namespace llvm;
|
|
|
|
// FIXME: Provide proper call frame setup / destroy opcodes.
|
|
MSP430RegisterInfo::MSP430RegisterInfo(MSP430TargetMachine &tm,
|
|
const TargetInstrInfo &tii)
|
|
: MSP430GenRegisterInfo(MSP430::PCW), TM(tm), TII(tii) {
|
|
StackAlign = TM.getFrameLowering()->getStackAlignment();
|
|
}
|
|
|
|
const uint16_t*
|
|
MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
|
const TargetFrameLowering *TFI = MF->getTarget().getFrameLowering();
|
|
const Function* F = MF->getFunction();
|
|
static const uint16_t CalleeSavedRegs[] = {
|
|
MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
|
|
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
|
|
0
|
|
};
|
|
static const uint16_t CalleeSavedRegsFP[] = {
|
|
MSP430::R5W, MSP430::R6W, MSP430::R7W,
|
|
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
|
|
0
|
|
};
|
|
static const uint16_t CalleeSavedRegsIntr[] = {
|
|
MSP430::FPW, MSP430::R5W, MSP430::R6W, MSP430::R7W,
|
|
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
|
|
MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
|
|
0
|
|
};
|
|
static const uint16_t CalleeSavedRegsIntrFP[] = {
|
|
MSP430::R5W, MSP430::R6W, MSP430::R7W,
|
|
MSP430::R8W, MSP430::R9W, MSP430::R10W, MSP430::R11W,
|
|
MSP430::R12W, MSP430::R13W, MSP430::R14W, MSP430::R15W,
|
|
0
|
|
};
|
|
|
|
if (TFI->hasFP(*MF))
|
|
return (F->getCallingConv() == CallingConv::MSP430_INTR ?
|
|
CalleeSavedRegsIntrFP : CalleeSavedRegsFP);
|
|
else
|
|
return (F->getCallingConv() == CallingConv::MSP430_INTR ?
|
|
CalleeSavedRegsIntr : CalleeSavedRegs);
|
|
|
|
}
|
|
|
|
BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|
BitVector Reserved(getNumRegs());
|
|
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
|
|
|
// Mark 4 special registers with subregisters as reserved.
|
|
Reserved.set(MSP430::PCB);
|
|
Reserved.set(MSP430::SPB);
|
|
Reserved.set(MSP430::SRB);
|
|
Reserved.set(MSP430::CGB);
|
|
Reserved.set(MSP430::PCW);
|
|
Reserved.set(MSP430::SPW);
|
|
Reserved.set(MSP430::SRW);
|
|
Reserved.set(MSP430::CGW);
|
|
|
|
// Mark frame pointer as reserved if needed.
|
|
if (TFI->hasFP(MF))
|
|
Reserved.set(MSP430::FPW);
|
|
|
|
return Reserved;
|
|
}
|
|
|
|
const TargetRegisterClass *
|
|
MSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
|
|
const {
|
|
return &MSP430::GR16RegClass;
|
|
}
|
|
|
|
void MSP430RegisterInfo::
|
|
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator I) const {
|
|
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
|
|
|
if (!TFI->hasReservedCallFrame(MF)) {
|
|
// If the stack pointer can be changed after prologue, turn the
|
|
// adjcallstackup instruction into a 'sub SPW, <amt>' and the
|
|
// adjcallstackdown instruction into 'add SPW, <amt>'
|
|
// TODO: consider using push / pop instead of sub + store / add
|
|
MachineInstr *Old = I;
|
|
uint64_t Amount = Old->getOperand(0).getImm();
|
|
if (Amount != 0) {
|
|
// We need to keep the stack aligned properly. To do this, we round the
|
|
// amount of space needed for the outgoing arguments up to the next
|
|
// alignment boundary.
|
|
Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
|
|
|
|
MachineInstr *New = 0;
|
|
if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
|
|
New = BuildMI(MF, Old->getDebugLoc(),
|
|
TII.get(MSP430::SUB16ri), MSP430::SPW)
|
|
.addReg(MSP430::SPW).addImm(Amount);
|
|
} else {
|
|
assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
|
|
// factor out the amount the callee already popped.
|
|
uint64_t CalleeAmt = Old->getOperand(1).getImm();
|
|
Amount -= CalleeAmt;
|
|
if (Amount)
|
|
New = BuildMI(MF, Old->getDebugLoc(),
|
|
TII.get(MSP430::ADD16ri), MSP430::SPW)
|
|
.addReg(MSP430::SPW).addImm(Amount);
|
|
}
|
|
|
|
if (New) {
|
|
// The SRW implicit def is dead.
|
|
New->getOperand(3).setIsDead();
|
|
|
|
// Replace the pseudo instruction with a new instruction...
|
|
MBB.insert(I, New);
|
|
}
|
|
}
|
|
} else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
|
|
// If we are performing frame pointer elimination and if the callee pops
|
|
// something off the stack pointer, add it back.
|
|
if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
|
|
MachineInstr *Old = I;
|
|
MachineInstr *New =
|
|
BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
|
|
MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
|
|
// The SRW implicit def is dead.
|
|
New->getOperand(3).setIsDead();
|
|
|
|
MBB.insert(I, New);
|
|
}
|
|
}
|
|
|
|
MBB.erase(I);
|
|
}
|
|
|
|
void
|
|
MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|
int SPAdj, RegScavenger *RS) const {
|
|
assert(SPAdj == 0 && "Unexpected");
|
|
|
|
unsigned i = 0;
|
|
MachineInstr &MI = *II;
|
|
MachineBasicBlock &MBB = *MI.getParent();
|
|
MachineFunction &MF = *MBB.getParent();
|
|
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
|
DebugLoc dl = MI.getDebugLoc();
|
|
while (!MI.getOperand(i).isFI()) {
|
|
++i;
|
|
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
|
|
}
|
|
|
|
int FrameIndex = MI.getOperand(i).getIndex();
|
|
|
|
unsigned BasePtr = (TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW);
|
|
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
|
|
|
|
// Skip the saved PC
|
|
Offset += 2;
|
|
|
|
if (!TFI->hasFP(MF))
|
|
Offset += MF.getFrameInfo()->getStackSize();
|
|
else
|
|
Offset += 2; // Skip the saved FPW
|
|
|
|
// Fold imm into offset
|
|
Offset += MI.getOperand(i+1).getImm();
|
|
|
|
if (MI.getOpcode() == MSP430::ADD16ri) {
|
|
// This is actually "load effective address" of the stack slot
|
|
// instruction. We have only two-address instructions, thus we need to
|
|
// expand it into mov + add
|
|
|
|
MI.setDesc(TII.get(MSP430::MOV16rr));
|
|
MI.getOperand(i).ChangeToRegister(BasePtr, false);
|
|
|
|
if (Offset == 0)
|
|
return;
|
|
|
|
// We need to materialize the offset via add instruction.
|
|
unsigned DstReg = MI.getOperand(0).getReg();
|
|
if (Offset < 0)
|
|
BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::SUB16ri), DstReg)
|
|
.addReg(DstReg).addImm(-Offset);
|
|
else
|
|
BuildMI(MBB, llvm::next(II), dl, TII.get(MSP430::ADD16ri), DstReg)
|
|
.addReg(DstReg).addImm(Offset);
|
|
|
|
return;
|
|
}
|
|
|
|
MI.getOperand(i).ChangeToRegister(BasePtr, false);
|
|
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
|
}
|
|
|
|
unsigned MSP430RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
|
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
|
|
|
return TFI->hasFP(MF) ? MSP430::FPW : MSP430::SPW;
|
|
}
|