diff options
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 16 | ||||
-rw-r--r-- | lib/Target/Mips/MipsMCInstLower.cpp | 33 | ||||
-rw-r--r-- | lib/Target/Mips/MipsMCInstLower.h | 2 |
3 files changed, 35 insertions, 16 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index cc25c4c..a5505d3 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -96,19 +96,17 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { if (!OutStreamer.hasRawTextSupport()) { // Lower CPLOAD and CPRESTORE - if (Opc == Mips::CPLOAD) { + if (Opc == Mips::CPLOAD) MCInstLowering.LowerCPLOAD(MI, MCInsts); - for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); I - != MCInsts.end(); ++I) + else if (Opc == Mips::CPRESTORE) + MCInstLowering.LowerCPRESTORE(MI, MCInsts); + + if (!MCInsts.empty()) { + for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin(); + I != MCInsts.end(); ++I) OutStreamer.EmitInstruction(*I); return; } - - if (Opc == Mips::CPRESTORE) { - MCInstLowering.LowerCPRESTORE(MI, TmpInst0); - OutStreamer.EmitInstruction(TmpInst0); - return; - } } OutStreamer.EmitInstruction(TmpInst0); 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, diff --git a/lib/Target/Mips/MipsMCInstLower.h b/lib/Target/Mips/MipsMCInstLower.h index 98e37e4..1490c14 100644 --- a/lib/Target/Mips/MipsMCInstLower.h +++ b/lib/Target/Mips/MipsMCInstLower.h @@ -36,7 +36,7 @@ public: MipsAsmPrinter &asmprinter); void Lower(const MachineInstr *MI, MCInst &OutMI) const; void LowerCPLOAD(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts); - void LowerCPRESTORE(const MachineInstr *MI, MCInst &OutMI); + void LowerCPRESTORE(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts); void LowerUnalignedLoadStore(const MachineInstr *MI, SmallVector<MCInst, 4>& MCInsts); private: |