diff --git a/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s b/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s index 72e79b77a01ad..489d385468b70 100644 --- a/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s +++ b/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind.s @@ -105,11 +105,7 @@ // CHECK-NEXT: CR: 0 // CHECK-NEXT: FrameSize: 112 // CHECK-NEXT: Prologue [ -// CHECK-NEXT: sub sp, sp, #48 -// CHECK-NEXT: stp x6, x7, [sp, #48] -// CHECK-NEXT: stp x4, x5, [sp, #32] -// CHECK-NEXT: stp x2, x3, [sp, #16] -// CHECK-NEXT: stp x0, x1, [sp, #-64]! +// CHECK-NEXT: sub sp, sp, #112 // CHECK-NEXT: end // CHECK-NEXT: ] // CHECK-NEXT: } @@ -276,6 +272,37 @@ // CHECK-NEXT: end // CHECK-NEXT: ] // CHECK-NEXT: } +// CHECK-NEXT: RuntimeFunction { +// CHECK-NEXT: Function: func17 +// CHECK-NEXT: Fragment: No +// CHECK-NEXT: FunctionLength: 44 +// CHECK-NEXT: RegF: 0 +// CHECK-NEXT: RegI: 0 +// CHECK-NEXT: HomedParameters: Yes +// CHECK-NEXT: CR: 3 +// CHECK-NEXT: FrameSize: 96 +// CHECK-NEXT: Prologue [ +// CHECK-NEXT: mov x29, sp +// CHECK-NEXT: stp x29, lr, [sp, #-96]! +// CHECK-NEXT: end +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: RuntimeFunction { +// CHECK-NEXT: Function: func18 +// CHECK-NEXT: Fragment: No +// CHECK-NEXT: FunctionLength: 44 +// CHECK-NEXT: RegF: 0 +// CHECK-NEXT: RegI: 0 +// CHECK-NEXT: HomedParameters: Yes +// CHECK-NEXT: CR: 3 +// CHECK-NEXT: FrameSize: 528 +// CHECK-NEXT: Prologue [ +// CHECK-NEXT: mov x29, sp +// CHECK-NEXT: stp x29, lr, [sp, #0] +// CHECK-NEXT: sub sp, sp, #528 +// CHECK-NEXT: end +// CHECK-NEXT: ] +// CHECK-NEXT: } // CHECK-NEXT: ] .text @@ -296,6 +323,8 @@ func13: func14: func15: func16: +func17: +func18: ret .section .pdata,"dr" @@ -331,3 +360,7 @@ func16: .long 0x11820019 // FunctionLength=6 RegF=0 RegI=2 H=0 CR=0 FrameSize=34 .long func16@IMGREL .long 0x03b00039 // FunctionLength=14 RegF=0 RegI=0 H=1 CR=1 FrameSize=7 + .long func17@IMGREL + .long 0x0370002d // FunctionLength=11 RegF=0 RegI=0 H=1 CR=3 FrameSize=6 + .long func18@IMGREL + .long 0x10f0002d // FunctionLength=11 RegF=0 RegI=0 H=1 CR=3 FrameSize=6 diff --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp index 3b2ea5b551117..32e3d059f44d3 100644 --- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp +++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp @@ -1404,6 +1404,12 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF, FpSZ += 8; int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf; int LocSZ = (RF.FrameSize() << 4) - SavSZ; + bool Homing = RF.H(); + + if (RF.H() && RF.RegI() == 0 && RF.RegF() == 0 && RF.CR() != 1) { + LocSZ += SavSZ; + Homing = false; + } if (RF.CR() == 2 || RF.CR() == 3) { SW.startLine() << "mov x29, sp\n"; @@ -1419,18 +1425,11 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF, } else if ((RF.CR() != 3 && RF.CR() != 2 && LocSZ > 0) || LocSZ > 512) { SW.startLine() << format("sub sp, sp, #%d\n", LocSZ); } - if (RF.H()) { + if (Homing) { SW.startLine() << format("stp x6, x7, [sp, #%d]\n", SavSZ - 16); SW.startLine() << format("stp x4, x5, [sp, #%d]\n", SavSZ - 32); SW.startLine() << format("stp x2, x3, [sp, #%d]\n", SavSZ - 48); - if (RF.RegI() > 0 || RF.RegF() > 0 || RF.CR() == 1) { - SW.startLine() << format("stp x0, x1, [sp, #%d]\n", SavSZ - 64); - } else { - // This case isn't documented; if neither RegI nor RegF nor CR=1 - // have decremented the stack pointer by SavSZ, we need to do it here - // (as the final stack adjustment of LocSZ excludes SavSZ). - SW.startLine() << format("stp x0, x1, [sp, #-%d]!\n", SavSZ); - } + SW.startLine() << format("stp x0, x1, [sp, #%d]\n", SavSZ - 64); } int FloatRegs = RF.RegF() > 0 ? RF.RegF() + 1 : 0; for (int I = (FloatRegs + 1) / 2 - 1; I >= 0; I--) {