From a3613be96342ab966eedec35d599068347185dc0 Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Fri, 10 Apr 2009 15:10:14 +0000 Subject: [PATCH] Added code to handle spilling and reloading of FSRs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68783 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PIC16/PIC16ISelLowering.cpp | 9 ++++--- lib/Target/PIC16/PIC16ISelLowering.h | 2 +- lib/Target/PIC16/PIC16InstrInfo.cpp | 37 +++++++++++++++++++++----- lib/Target/PIC16/PIC16InstrInfo.td | 27 ++++++++++++++++--- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index 550ac5bc289..e0603bbbef2 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -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::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); diff --git a/lib/Target/PIC16/PIC16ISelLowering.h b/lib/Target/PIC16/PIC16ISelLowering.h index 8b441c861a1..03397beab18 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.h +++ b/lib/Target/PIC16/PIC16ISelLowering.h @@ -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 diff --git a/lib/Target/PIC16/PIC16InstrInfo.cpp b/lib/Target/PIC16/PIC16InstrInfo.cpp index 99c27fdac77..8d8a0199540 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.cpp +++ b/lib/Target/PIC16/PIC16InstrInfo.cpp @@ -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"); } diff --git a/lib/Target/PIC16/PIC16InstrInfo.td b/lib/Target/PIC16/PIC16InstrInfo.td index 04c3fc6eb8d..abdabc68ca9 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.td +++ b/lib/Target/PIC16/PIC16InstrInfo.td @@ -232,6 +232,24 @@ def copy_fsr: def copy_w: Pseudo<(outs GPR:$dst), (ins GPR:$src), "copy_w $dst, $src", []>; +class SAVE_FSR: + 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: + 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",