diff --git a/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/llvm/lib/Target/Mips/MipsFrameLowering.cpp index 8b4e23876e8b..22d1e47b1a2b 100644 --- a/llvm/lib/Target/Mips/MipsFrameLowering.cpp +++ b/llvm/lib/Target/Mips/MipsFrameLowering.cpp @@ -254,9 +254,15 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const { } // Restore GP from the saved stack location - if (MipsFI->needGPSaveRestore()) - BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)) - .addImm(MFI->getObjectOffset(MipsFI->getGPFI())); + if (MipsFI->needGPSaveRestore()) { + unsigned Offset = MFI->getObjectOffset(MipsFI->getGPFI()); + BuildMI(MBB, MBBI, dl, TII.get(Mips::CPRESTORE)).addImm(Offset); + + if (Offset >= 0x8000) { + BuildMI(MBB, llvm::prior(MBBI), dl, TII.get(Mips::MACRO)); + BuildMI(MBB, MBBI, dl, TII.get(Mips::NOMACRO)); + } + } } void MipsFrameLowering::emitEpilogue(MachineFunction &MF, diff --git a/llvm/test/CodeGen/Mips/cprestore.ll b/llvm/test/CodeGen/Mips/cprestore.ll new file mode 100644 index 000000000000..a275c8b7a556 --- /dev/null +++ b/llvm/test/CodeGen/Mips/cprestore.ll @@ -0,0 +1,16 @@ +; RUN: llc -march=mipsel < %s | FileCheck %s + +; CHECK: .set macro +; CHECK-NEXT: .cprestore +; CHECK-NEXT: .set nomacro + +%struct.S = type { [16384 x i32] } + +define void @foo2() nounwind { +entry: + %s = alloca %struct.S, align 4 + call void @foo1(%struct.S* byval %s) + ret void +} + +declare void @foo1(%struct.S* byval)