From 044a784fa586cf92bb712c6dc54f925f539e19d1 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Tue, 13 Dec 2011 03:09:05 +0000 Subject: Expand .cprestore directive to multiple instructions if the offset does not fit in a 16-bit field. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146469 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsMCInstLower.cpp | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'lib/Target/Mips/MipsMCInstLower.cpp') diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index 8181291..de65881 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -137,14 +137,35 @@ void MipsMCInstLower::LowerCPLOAD(const MachineInstr *MI, } // Lower ".cprestore offset" to "sw $gp, offset($sp)". -void MipsMCInstLower::LowerCPRESTORE(const MachineInstr *MI, MCInst &OutMI) { - OutMI.clear(); - OutMI.setOpcode(Mips::SW); - OutMI.addOperand(MCOperand::CreateReg(Mips::GP)); - OutMI.addOperand(MCOperand::CreateReg(Mips::SP)); +void MipsMCInstLower::LowerCPRESTORE(const MachineInstr *MI, + SmallVector& MCInsts) { const MachineOperand &MO = MI->getOperand(0); assert(MO.isImm() && "CPRESTORE's operand must be an immediate."); - OutMI.addOperand(MCOperand::CreateImm(MO.getImm())); + unsigned Offset = MO.getImm(), Reg = Mips::SP; + MCInst Sw; + + if (Offset >= 0x8000) { + unsigned Hi = (Offset >> 16) + ((Offset & 0x8000) != 0); + Offset &= 0xffff; + Reg = Mips::AT; + + // lui at,hi + // addu at,at,sp + MCInsts.resize(2); + MCInsts[0].setOpcode(Mips::LUi); + MCInsts[0].addOperand(MCOperand::CreateReg(Mips::AT)); + MCInsts[0].addOperand(MCOperand::CreateImm(Hi)); + MCInsts[1].setOpcode(Mips::ADDu); + MCInsts[1].addOperand(MCOperand::CreateReg(Mips::AT)); + MCInsts[1].addOperand(MCOperand::CreateReg(Mips::AT)); + MCInsts[1].addOperand(MCOperand::CreateReg(Mips::SP)); + } + + Sw.setOpcode(Mips::SW); + Sw.addOperand(MCOperand::CreateReg(Mips::GP)); + Sw.addOperand(MCOperand::CreateReg(Reg)); + Sw.addOperand(MCOperand::CreateImm(Offset)); + MCInsts.push_back(Sw); } MCOperand MipsMCInstLower::LowerOperand(const MachineOperand& MO, -- cgit v1.1