Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Unified Diff: lib/Target/ARM/ARMFrameLowering.cpp

Issue 1154253004: Use R0/R1 instead of R4/R5 for ARM eh_return return values (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/Target/ARM/ARMFrameLowering.cpp
diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp
index 8895dfa5c8e0b6ca1a503f5671c966ba5b4810b7..bb10fe21bf23779b1179afbfcd95bd064019e640 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -966,6 +966,15 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB,
isKill = false;
}
+ // @LOCALMOD-START
+ // Functions which call EHReturn spill all CSRs plus R0/R1
+ if ((Reg == ARM::R0 || Reg == ARM::R1) &&
+ MF.getRegInfo().isLiveIn(Reg)) {
+ assert(MF.getMMI().callsEHReturn());
+ isKill = false;
+ }
+ // @LOCALMOD-END
+
if (isKill)
MBB.addLiveIn(Reg);
@@ -1025,6 +1034,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
while (i != 0) {
unsigned LastReg = 0;
bool DeleteRet = false;
+ unsigned SkippedPop = 0; // @LOCALMOD
for (; i != 0; --i) {
unsigned Reg = CSI[i-1].getReg();
if (!(Func)(Reg, STI.isTargetDarwin())) continue;
@@ -1033,6 +1043,19 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
continue;
+ // @LOCALMOD-START
+ // Functions which call EHReturn spill all of their CSRs plus R0 and R1,
+ // (the EHReturn return value registers). Epilogs which return via
+ // EHreturn pop all of them, but epilogs which return via normal return
+ // must not restore R0 and R1, as that would clobber the return value.
+ if (MF.getMMI().callsEHReturn() &&
+ RetOpcode != ARM::ARMeh_return &&
+ (Reg == ARM::R0 || Reg == ARM::R1)) {
+ SkippedPop++;
+ continue;
+ }
+ // @LOCALMOD-END
+
if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
STI.hasV5TOps() &&
!STI.isTargetNaCl() /* @LOCALMOD */) {
@@ -1052,12 +1075,27 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
Regs.push_back(Reg);
}
+ // @LOCALMOD-START
+ if (SkippedPop) {
+ // We need to increment the stack pointer to compensate for the skipped
+ // pops. However we cannot directly increment it because the epilog
+ // insertion code places the stack pointer restore before the CSR restores;
jvoung (off chromium) 2015/06/03 17:19:38 80 col
Derek Schuff 2015/06/03 20:50:57 Done.
+ // it does this by finding the first instruction that's not a pop.
+ // If we put an add here, the restore would go in between the restore of
+ // the FP registers and the GPRs, instead of before the FP restore. So
+ // use a pop into R12 to adjust SP.
+ while(SkippedPop--)
+ AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(LdmOpc), ARM::SP)
+ .addReg(ARM::SP)).addReg(ARM::R12);
+ }
+ // @LOCALMOD-END
+
if (Regs.empty())
continue;
if (Regs.size() > 1 || LdrOpc == 0) {
MachineInstrBuilder MIB =
- AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(LdmOpc), ARM::SP)
- .addReg(ARM::SP));
+ AddDefaultPred(BuildMI(MBB, MI, DL, TII.get(LdmOpc), ARM::SP)
+ .addReg(ARM::SP));
jvoung (off chromium) 2015/06/03 17:19:38 revert whitespace change?
Derek Schuff 2015/06/03 20:50:57 Done.
for (unsigned i = 0, e = Regs.size(); i < e; ++i)
MIB.addReg(Regs[i], getDefRegState(true));
if (DeleteRet) {

Powered by Google App Engine
This is Rietveld 408576698