aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Mips/MipsMCInstLower.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@mips.com>2011-12-13 03:09:05 +0000
committerAkira Hatanaka <ahatanaka@mips.com>2011-12-13 03:09:05 +0000
commit044a784fa586cf92bb712c6dc54f925f539e19d1 (patch)
treed634b12b3ed144c2ab380eb5560ac8774e87374a /lib/Target/Mips/MipsMCInstLower.cpp
parentf3315cf65f9574cd1e4e784d2860c943cfa65ce9 (diff)
downloadexternal_llvm-044a784fa586cf92bb712c6dc54f925f539e19d1.zip
external_llvm-044a784fa586cf92bb712c6dc54f925f539e19d1.tar.gz
external_llvm-044a784fa586cf92bb712c6dc54f925f539e19d1.tar.bz2
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
Diffstat (limited to 'lib/Target/Mips/MipsMCInstLower.cpp')
-rw-r--r--lib/Target/Mips/MipsMCInstLower.cpp33
1 files changed, 27 insertions, 6 deletions
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<MCInst, 4>& 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,