Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 46 additions & 19 deletions llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,28 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
}
}
assert(RBReg != ScratchReg && "Should have avoided ScratchReg");

// Lambda to build MTCRF/MTOCRF instruction for restoring CR fields
auto BuildMoveToCR = [&](MachineBasicBlock::iterator InsertPt,
Register SrcReg) {
if (MustSaveCRs.size() == 1) {
// Use MTOCRF for single CR field
BuildMI(MBB, InsertPt, dl, MoveToCRInst, MustSaveCRs[0])
.addReg(SrcReg, getKillRegState(true));
} else {
// Build CR mask for MTCRF - more efficient than multiple MTOCRF
unsigned CRMask = 0;
for (unsigned CRField : MustSaveCRs) {
unsigned CRNum = CRField - PPC::CR0;
CRMask |= (0x80 >> CRNum);
}
// Use single MTCRF to restore multi CR fields at once
BuildMI(MBB, InsertPt, dl, TII.get(isPPC64 ? PPC::MTCRF8 : PPC::MTCRF))
.addImm(CRMask)
.addReg(SrcReg, getKillRegState(true));
}
};

// If there is no red zone, ScratchReg may be needed for holding a useful
// value (although not the base register). Make sure it is not overwritten
// too early.
Expand All @@ -1781,9 +1803,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
BuildMI(MBB, MBBI, dl, LoadWordInst, TempReg)
.addImm(CRSaveOffset)
.addReg(SPReg);
for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
.addReg(TempReg, getKillRegState(i == e-1));
BuildMoveToCR(MBBI, TempReg);
}

// Delay restoring of the LR if ScratchReg is needed. This is ok, since
Expand Down Expand Up @@ -1857,9 +1877,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,

if (MustSaveCR &&
!(SingleScratchReg && MustSaveLR))
for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)
BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])
.addReg(TempReg, getKillRegState(i == e-1));
BuildMoveToCR(MBBI, TempReg);

if (MustSaveLR) {
// If ROP protection is required, an extra instruction is added to compute a
Expand Down Expand Up @@ -2545,19 +2563,28 @@ static void restoreCRs(bool is31, bool CR2Spilled, bool CR3Spilled,
MBB.insert(MI,
addFrameReference(BuildMI(*MF, DL, TII.get(PPC::LWZ), MoveReg),
CSI[CSIIndex].getFrameIdx()));

unsigned RestoreOp = PPC::MTOCRF;
if (CR2Spilled)
MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR2)
.addReg(MoveReg, getKillRegState(!CR3Spilled && !CR4Spilled)));

if (CR3Spilled)
MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR3)
.addReg(MoveReg, getKillRegState(!CR4Spilled)));

if (CR4Spilled)
MBB.insert(MI, BuildMI(*MF, DL, TII.get(RestoreOp), PPC::CR4)
.addReg(MoveReg, getKillRegState(true)));
// Count how many CR fields need restoring
unsigned NumCRs =
(CR2Spilled ? 1 : 0) + (CR3Spilled ? 1 : 0) + (CR4Spilled ? 1 : 0);

if (NumCRs == 1) {
// Use MTOCRF for single field
unsigned CRReg = CR2Spilled ? PPC::CR2 : (CR3Spilled ? PPC::CR3 : PPC::CR4);
MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MTOCRF), CRReg)
.addReg(MoveReg, getKillRegState(true)));
} else if (NumCRs > 1) {
// Use MTCRF for multiple fields (1 instruction vs N)
unsigned CRMask = 0;
if (CR2Spilled)
CRMask |= 0x20;
if (CR3Spilled)
CRMask |= 0x10;
if (CR4Spilled)
CRMask |= 0x08;
MBB.insert(MI, BuildMI(*MF, DL, TII.get(PPC::MTCRF))
.addImm(CRMask)
.addReg(MoveReg, getKillRegState(true)));
}
}

MachineBasicBlock::iterator PPCFrameLowering::
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/PowerPC/2010-02-12-saveCR.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ entry:
return: ; preds = %entry
; CHECK: ori [[T2]], [[T2]], 34492
; CHECK: lwzx [[T1]], 1, [[T2]]
; CHECK: mtcrf 32, [[T1]]
; CHECK: mtcrf 16, [[T1]]
; CHECK: mtcrf 48, [[T1]]
ret void
}

Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/PowerPC/aix-crspill.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ declare signext i32 @do_something(i32 signext)
; 64BIT-NEXT: ld 0, 16(1)
; 64BIT-NEXT: lwz 12, 8(1)
; 64BIT-NEXT: mtlr 0
; 64BIT-NEXT: mtocrf 32, 12
; 64BIT-NEXT: mtocrf 16, 12
; 64BIT-NEXT: mtocrf 8, 12
; 64BIT-NEXT: mtcrf 56, 12
; 64BIT-NEXT: blr


Expand All @@ -75,7 +73,5 @@ declare signext i32 @do_something(i32 signext)
; 32BIT-NEXT: lwz 0, 8(1)
; 32BIT-NEXT: lwz 12, 4(1)
; 32BIT-NEXT: mtlr 0
; 32BIT-NEXT: mtocrf 32, 12
; 32BIT-NEXT: mtocrf 16, 12
; 32BIT-NEXT: mtocrf 8, 12
; 32BIT-NEXT: mtcrf 56, 12
; 32BIT-NEXT: blr
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/PowerPC/aix32-crsave.mir
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ body: |
; CHECK-NEXT: $r30 = LWZ -8, $r1 :: (load (s32) from %fixed-stack.1, align 8)
; CHECK-NEXT: $r29 = LWZ -12, $r1 :: (load (s32) from %fixed-stack.2)
; CHECK-NEXT: $r12 = LWZ 4, $r1
; CHECK-NEXT: $cr2 = MTOCRF $r12
; CHECK-NEXT: $cr4 = MTOCRF killed $r12
; CHECK-NEXT: MTCRF 40, killed $r12

...
---
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/PowerPC/cc.ll
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ end:
; CHECK: mtocrf 128, [[REG3]]

; CHECK: lwz [[REG4:[0-9]+]], 8(1)
; CHECK-DAG: mtocrf 32, [[REG4]]
; CHECK-DAG: mtocrf 16, [[REG4]]
; CHECK-DAG: mtocrf 8, [[REG4]]
; CHECK-DAG: mtcrf 56, [[REG4]]
; CHECK: blr
}

Expand Down Expand Up @@ -62,9 +60,7 @@ end:
; CHECK: mtocrf 128, [[REG3]]

; CHECK: lwz [[REG4:[0-9]+]], 8(1)
; CHECK-DAG: mtocrf 32, [[REG4]]
; CHECK-DAG: mtocrf 16, [[REG4]]
; CHECK-DAG: mtocrf 8, [[REG4]]
; CHECK-DAG: mtcrf 56, [[REG4]]
; CHECK: blr
}

24 changes: 6 additions & 18 deletions llvm/test/CodeGen/PowerPC/crsave.ll
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,7 @@ define i32 @test_cr234() nounwind {
; PPC32-NEXT: bl foo
; PPC32-NEXT: lwz 3, 20(31)
; PPC32-NEXT: lwz 12, 24(31)
; PPC32-NEXT: mtocrf 32, 12
; PPC32-NEXT: mtocrf 16, 12
; PPC32-NEXT: mtocrf 8, 12
; PPC32-NEXT: mtcrf 56, 12
; PPC32-NEXT: lwz 0, 36(1)
; PPC32-NEXT: lwz 31, 28(1)
; PPC32-NEXT: addi 1, 1, 32
Expand Down Expand Up @@ -172,9 +170,7 @@ define i32 @test_cr234() nounwind {
; PPC64-NEXT: addi 1, 1, 128
; PPC64-NEXT: ld 0, 16(1)
; PPC64-NEXT: lwz 12, 8(1)
; PPC64-NEXT: mtocrf 32, 12
; PPC64-NEXT: mtocrf 16, 12
; PPC64-NEXT: mtocrf 8, 12
; PPC64-NEXT: mtcrf 56, 12
; PPC64-NEXT: mtlr 0
; PPC64-NEXT: blr
;
Expand Down Expand Up @@ -204,9 +200,7 @@ define i32 @test_cr234() nounwind {
; PPC64-ELFv2-NEXT: addi 1, 1, 112
; PPC64-ELFv2-NEXT: ld 0, 16(1)
; PPC64-ELFv2-NEXT: lwz 12, 8(1)
; PPC64-ELFv2-NEXT: mtocrf 32, 12
; PPC64-ELFv2-NEXT: mtocrf 16, 12
; PPC64-ELFv2-NEXT: mtocrf 8, 12
; PPC64-ELFv2-NEXT: mtcrf 56, 12
; PPC64-ELFv2-NEXT: mtlr 0
; PPC64-ELFv2-NEXT: blr
entry:
Expand Down Expand Up @@ -285,9 +279,7 @@ define void @cloberAllNvCrField() {
; PPC32-NEXT: # clobbers
; PPC32-NEXT: #NO_APP
; PPC32-NEXT: lwz 12, 24(31)
; PPC32-NEXT: mtocrf 32, 12
; PPC32-NEXT: mtocrf 16, 12
; PPC32-NEXT: mtocrf 8, 12
; PPC32-NEXT: mtcrf 56, 12
; PPC32-NEXT: lwz 31, 28(1)
; PPC32-NEXT: addi 1, 1, 32
; PPC32-NEXT: blr
Expand All @@ -300,9 +292,7 @@ define void @cloberAllNvCrField() {
; PPC64-NEXT: # clobbers
; PPC64-NEXT: #NO_APP
; PPC64-NEXT: lwz 12, 8(1)
; PPC64-NEXT: mtocrf 32, 12
; PPC64-NEXT: mtocrf 16, 12
; PPC64-NEXT: mtocrf 8, 12
; PPC64-NEXT: mtcrf 56, 12
; PPC64-NEXT: blr
;
; PPC64-ELFv2-LABEL: cloberAllNvCrField:
Expand All @@ -313,9 +303,7 @@ define void @cloberAllNvCrField() {
; PPC64-ELFv2-NEXT: # clobbers
; PPC64-ELFv2-NEXT: #NO_APP
; PPC64-ELFv2-NEXT: lwz 12, 8(1)
; PPC64-ELFv2-NEXT: mtocrf 32, 12
; PPC64-ELFv2-NEXT: mtocrf 16, 12
; PPC64-ELFv2-NEXT: mtocrf 8, 12
; PPC64-ELFv2-NEXT: mtcrf 56, 12
; PPC64-ELFv2-NEXT: blr
entry:
tail call void asm sideeffect "# clobbers", "~{cr2},~{cr3},~{cr4}"()
Expand Down
4 changes: 1 addition & 3 deletions llvm/test/CodeGen/PowerPC/p10-spill-creq.ll
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@ define dso_local double @P10_Spill_CR_EQ(ptr %arg) local_unnamed_addr #0 {
; CHECK-NEXT: mtocrf 128, r7
; CHECK-NEXT: isel r5, 0, r6, 4*cr6+lt
; CHECK-NEXT: isel r3, 0, r3, 4*cr1+eq
; CHECK-NEXT: mtocrf 32, r12
; CHECK-NEXT: mtocrf 16, r12
; CHECK-NEXT: mtocrf 8, r12
; CHECK-NEXT: mtcrf 56, r12
; CHECK-NEXT: crandc 4*cr5+lt, 4*cr5+lt, eq
; CHECK-NEXT: isel r5, 0, r5, 4*cr7+eq
; CHECK-NEXT: crnor 4*cr5+lt, 4*cr5+un, 4*cr5+lt
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/PowerPC/p10-spill-crgt.ll
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,7 @@ define dso_local fastcc void @P10_Spill_CR_GT(ptr %p) unnamed_addr {
; CHECK-NEXT: ld r0, 16(r1)
; CHECK-NEXT: lwz r12, 8(r1)
; CHECK-NEXT: mtlr r0
; CHECK-NEXT: mtocrf 32, r12
; CHECK-NEXT: mtocrf 16, r12
; CHECK-NEXT: mtocrf 8, r12
; CHECK-NEXT: mtcrf 56, r12
; CHECK-NEXT: blr
; CHECK-NEXT: .LBB0_32: # %bb29
; CHECK-NEXT: crmove eq, 4*cr3+eq
Expand Down Expand Up @@ -382,9 +380,7 @@ define dso_local fastcc void @P10_Spill_CR_GT(ptr %p) unnamed_addr {
; CHECK-BE-NEXT: ld r0, 16(r1)
; CHECK-BE-NEXT: lwz r12, 8(r1)
; CHECK-BE-NEXT: mtlr r0
; CHECK-BE-NEXT: mtocrf 32, r12
; CHECK-BE-NEXT: mtocrf 16, r12
; CHECK-BE-NEXT: mtocrf 8, r12
; CHECK-BE-NEXT: mtcrf 56, r12
; CHECK-BE-NEXT: blr
; CHECK-BE-NEXT: .LBB0_32: # %bb29
; CHECK-BE-NEXT: crmove eq, 4*cr3+eq
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/PowerPC/p10-spill-crun.ll
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,7 @@ define dso_local void @P10_Spill_CR_UN(ptr %arg, ptr %arg1, i32 %arg2) local_unn
; CHECK-NEXT: ld r0, 16(r1)
; CHECK-NEXT: lwz r12, 8(r1)
; CHECK-NEXT: mtlr r0
; CHECK-NEXT: mtocrf 32, r12
; CHECK-NEXT: mtocrf 16, r12
; CHECK-NEXT: mtocrf 8, r12
; CHECK-NEXT: mtcrf 56, r12
; CHECK-NEXT: blr
; CHECK-NEXT: .LBB0_18: # %bb30
; CHECK-NEXT: stb r3, 181(r1)
Expand Down Expand Up @@ -333,9 +331,7 @@ define dso_local void @P10_Spill_CR_UN(ptr %arg, ptr %arg1, i32 %arg2) local_unn
; CHECK-BE-NEXT: ld r0, 16(r1)
; CHECK-BE-NEXT: lwz r12, 8(r1)
; CHECK-BE-NEXT: mtlr r0
; CHECK-BE-NEXT: mtocrf 32, r12
; CHECK-BE-NEXT: mtocrf 16, r12
; CHECK-BE-NEXT: mtocrf 8, r12
; CHECK-BE-NEXT: mtcrf 56, r12
; CHECK-BE-NEXT: blr
; CHECK-BE-NEXT: .LBB0_18: # %bb30
; CHECK-BE-NEXT: stb r3, 197(r1)
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/CodeGen/PowerPC/ppc64-crsave.mir
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ body: |
; SAVEONE-NEXT: renamable $cr2lt = COPY $cr0gt
; SAVEONE-NEXT: renamable $cr4lt = COPY $cr0gt
; SAVEONE-NEXT: $x12 = LWZ8 8, $x1
; SAVEONE-NEXT: $cr2 = MTOCRF8 $x12
; SAVEONE-NEXT: $cr4 = MTOCRF8 killed $x12
; SAVEONE-NEXT: MTCRF8 40, killed $x12
; SAVEONE-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3
;
; SAVEALL-LABEL: name: CRAllSave
Expand All @@ -42,8 +41,7 @@ body: |
; SAVEALL-NEXT: renamable $cr2lt = COPY $cr0gt
; SAVEALL-NEXT: renamable $cr4lt = COPY $cr0gt
; SAVEALL-NEXT: $x12 = LWZ8 8, $x1
; SAVEALL-NEXT: $cr2 = MTOCRF8 $x12
; SAVEALL-NEXT: $cr4 = MTOCRF8 killed $x12
; SAVEALL-NEXT: MTCRF8 40, killed $x12
; SAVEALL-NEXT: BLR8 implicit $lr8, implicit $rm, implicit $x3
renamable $x3 = ANDI8_rec killed renamable $x3, 1, implicit-def dead $cr0, implicit-def $cr0gt
renamable $cr2lt = COPY $cr0gt
Expand Down
Loading
Loading