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:
parent
88986ef511
commit
6962a75641
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user