1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Added code to handle spilling and reloading of FSRs.

llvm-svn: 68783
This commit is contained in:
Sanjiv Gupta 2009-04-10 15:10:14 +00:00
parent 88986ef511
commit 6962a75641
4 changed files with 61 additions and 14 deletions

View File

@ -153,7 +153,7 @@ static SDValue getOutFlag(SDValue &Op) {
return Flag;
}
// Get the TmpOffset for FrameIndex
unsigned PIC16TargetLowering::GetTmpOffsetForFI(unsigned FI) {
unsigned PIC16TargetLowering::GetTmpOffsetForFI(unsigned FI, unsigned size) {
std::map<unsigned, unsigned>::iterator
MapIt = FiTmpOffsetMap.find(FI);
if (MapIt != FiTmpOffsetMap.end())
@ -161,7 +161,8 @@ unsigned PIC16TargetLowering::GetTmpOffsetForFI(unsigned FI) {
// This FI (FrameIndex) is not yet mapped, so map it
FiTmpOffsetMap[FI] = TmpSize;
return TmpSize++;
TmpSize += size;
return FiTmpOffsetMap[FI];
}
// To extract chain value from the SDValue Nodes
@ -849,14 +850,14 @@ SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
DAG.getEntryNode(),
Op, ES,
DAG.getConstant (1, MVT::i8), // Banksel.
DAG.getConstant (GetTmpOffsetForFI(FI),
DAG.getConstant (GetTmpOffsetForFI(FI, 1),
MVT::i8));
// Load the value from ES.
SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, dl, Tys, Store,
ES, DAG.getConstant (1, MVT::i8),
DAG.getConstant (GetTmpOffsetForFI(FI),
DAG.getConstant (GetTmpOffsetForFI(FI, 1),
MVT::i8));
return Load.getValue(0);

View File

@ -137,7 +137,7 @@ namespace llvm {
// This function returns the Tmp Offset for FrameIndex. If any TmpOffset
// already exists for the FI then it returns the same else it creates the
// new offset and returns.
unsigned GetTmpOffsetForFI(unsigned FI);
unsigned GetTmpOffsetForFI(unsigned FI, unsigned slot_size);
void ResetTmpOffsetMap() { FiTmpOffsetMap.clear(); SetTmpSize(0); }
// Return the size of Tmp variable

View File

@ -85,12 +85,25 @@ void PIC16InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
//MachineRegisterInfo &RI = MF.getRegInfo();
BuildMI(MBB, I, DL, get(PIC16::movwf))
.addReg(SrcReg, false, false, isKill)
.addImm(PTLI->GetTmpOffsetForFI(FI))
.addImm(PTLI->GetTmpOffsetForFI(FI, 1))
.addExternalSymbol(tmpName)
.addImm(1); // Emit banksel for it.
}
else if (RC == PIC16::FSR16RegisterClass) {
// This is a 16-bit register and the frameindex given by llvm is of
// size two here. Break this index N into two zero based indexes and
// put one into the map. The second one is always obtained by adding 1
// to the first zero based index. In fact it is going to use 3 slots
// as saving FSRs corrupts W also and hence we need to save/restore W also.
unsigned opcode = (SrcReg == PIC16::FSR0) ? PIC16::save_fsr0
: PIC16::save_fsr1;
BuildMI(MBB, I, DL, get(opcode))
.addReg(SrcReg, false, false, isKill)
.addImm(PTLI->GetTmpOffsetForFI(FI, 3))
.addExternalSymbol(tmpName)
.addImm(1); // Emit banksel for it.
}
else if (RC == PIC16::FSR16RegisterClass)
assert(0 && "Don't know yet how to store a FSR16 to stack slot");
else
assert(0 && "Can't store this register to stack slot");
}
@ -114,12 +127,24 @@ void PIC16InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
//MachineFunction &MF = *MBB.getParent();
//MachineRegisterInfo &RI = MF.getRegInfo();
BuildMI(MBB, I, DL, get(PIC16::movf), DestReg)
.addImm(PTLI->GetTmpOffsetForFI(FI))
.addImm(PTLI->GetTmpOffsetForFI(FI, 1))
.addExternalSymbol(tmpName)
.addImm(1); // Emit banksel for it.
}
else if (RC == PIC16::FSR16RegisterClass) {
// This is a 16-bit register and the frameindex given by llvm is of
// size two here. Break this index N into two zero based indexes and
// put one into the map. The second one is always obtained by adding 1
// to the first zero based index. In fact it is going to use 3 slots
// as saving FSRs corrupts W also and hence we need to save/restore W also.
unsigned opcode = (DestReg == PIC16::FSR0) ? PIC16::restore_fsr0
: PIC16::restore_fsr1;
BuildMI(MBB, I, DL, get(opcode), DestReg)
.addImm(PTLI->GetTmpOffsetForFI(FI, 3))
.addExternalSymbol(tmpName)
.addImm(1); // Emit banksel for it.
}
else if (RC == PIC16::FSR16RegisterClass)
assert(0 && "Don't know yet how to load an FSR16 from stack slot");
else
assert(0 && "Can't load this register from stack slot");
}

View File

@ -232,6 +232,24 @@ def copy_fsr:
def copy_w:
Pseudo<(outs GPR:$dst), (ins GPR:$src), "copy_w $dst, $src", []>;
class SAVE_FSR<string OpcStr>:
Pseudo<(outs),
(ins FSR16:$src, i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
!strconcat(OpcStr, " $ptrlo, $offset"),
[]>;
def save_fsr0: SAVE_FSR<"save_fsr0">;
def save_fsr1: SAVE_FSR<"save_fsr1">;
class RESTORE_FSR<string OpcStr>:
Pseudo<(outs FSR16:$dst),
(ins i8imm:$offset, i8mem:$ptrlo, i8imm:$ptrhi),
!strconcat(OpcStr, " $ptrlo, $offset"),
[]>;
def restore_fsr0: RESTORE_FSR<"restore_fsr0">;
def restore_fsr1: RESTORE_FSR<"restore_fsr1">;
//--------------------------
// Store to memory
//-------------------------
@ -397,19 +415,22 @@ def sublw_cc : SUBLW<0, PIC16Subcc>;
}
// Call instruction.
let isCall = 1 in {
let isCall = 1,
Defs = [W, FSR0, FSR1] in {
def CALL: LiteralFormat<0x1, (outs), (ins i8imm:$func),
"call ${func} + 2",
[(PIC16call diraddr:$func)]>;
}
let isCall = 1 in {
let isCall = 1,
Defs = [W, FSR0, FSR1] in {
def CALL_1: LiteralFormat<0x1, (outs), (ins GPR:$func, PCLATHR:$pc),
"callw",
[(PIC16call (PIC16Connect GPR:$func, PCLATHR:$pc))]>;
}
let isCall = 1 in {
let isCall = 1,
Defs = [FSR0, FSR1] in {
def CALLW: LiteralFormat<0x1, (outs GPR:$dest),
(ins GPR:$func, PCLATHR:$pc),
"callw",