// This test checks that the epilogue is packed where possible. // RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o // RUN: llvm-readobj -u %t.o | FileCheck %s // CHECK: UnwindInformation [ // CHECK-NEXT: RuntimeFunction { // CHECK-NEXT: Function: func // CHECK-NEXT: ExceptionRecord: .xdata // CHECK-NEXT: ExceptionData { // CHECK-NEXT: FunctionLength: // CHECK-NEXT: Version: // CHECK-NEXT: ExceptionData: // CHECK-NEXT: EpiloguePacked: Yes // CHECK-NEXT: EpilogueOffset: 2 // CHECK-NEXT: ByteCodeLength: // CHECK-NEXT: Prologue [ // CHECK-NEXT: 0xdc04 ; str d8, [sp, #32] // CHECK-NEXT: 0xe1 ; mov fp, sp // CHECK-NEXT: 0x42 ; stp x29, x30, [sp, #16] // CHECK-NEXT: 0x85 ; stp x29, x30, [sp, #-48]! // CHECK-NEXT: 0xe6 ; save next // CHECK-NEXT: 0x24 ; stp x19, x20, [sp, #-32]! // CHECK-NEXT: 0xc842 ; stp x20, x21, [sp, #16] // CHECK-NEXT: 0x03 ; sub sp, #48 // CHECK-NEXT: 0xe4 ; end // CHECK-NEXT: ] // CHECK-NEXT: Epilogue [ // CHECK-NEXT: 0xe1 ; mov sp, fp // CHECK-NEXT: 0x42 ; ldp x29, x30, [sp, #16] // CHECK-NEXT: 0x85 ; ldp x29, x30, [sp], #48 // CHECK-NEXT: 0xe6 ; restore next // CHECK-NEXT: 0x24 ; ldp x19, x20, [sp], #32 // CHECK-NEXT: 0xc842 ; ldp x20, x21, [sp, #16] // CHECK-NEXT: 0x03 ; add sp, #48 // CHECK-NEXT: 0xe4 ; end // CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: RuntimeFunction { // CHECK-NEXT: Function: packed2 // CHECK-NEXT: ExceptionRecord: // CHECK-NEXT: ExceptionData { // CHECK: ExceptionData: // CHECK-NEXT: EpiloguePacked: Yes // CHECK: RuntimeFunction { // CHECK-NEXT: Function: nonpacked1 // CHECK-NEXT: ExceptionRecord: // CHECK-NEXT: ExceptionData { // CHECK: ExceptionData: // CHECK-NEXT: EpiloguePacked: No // CHECK: RuntimeFunction { // CHECK-NEXT: Function: nonpacked2 // CHECK-NEXT: ExceptionRecord: // CHECK-NEXT: ExceptionData { // CHECK: ExceptionData: // CHECK-NEXT: EpiloguePacked: No // CHECK: RuntimeFunction { // CHECK-NEXT: Function: nonpacked3 // CHECK-NEXT: ExceptionRecord: // CHECK-NEXT: ExceptionData { // CHECK: ExceptionData: // CHECK-NEXT: EpiloguePacked: No .text .globl func .seh_proc func func: sub sp, sp, #48 .seh_stackalloc 48 // Check that canonical opcode forms (r19r20_x, fplr, fplr_x, save_next, // set_fp) are treated as a match even if one (in prologue or epilogue) // was simplified from the more generic opcodes. stp x20, x21, [sp, #16] .seh_save_regp x20, 16 stp x19, x20, [sp, #-32]! .seh_save_r19r20_x 32 stp x21, x22, [sp, #16] .seh_save_regp x21, 16 stp x29, x30, [sp, #-48]! .seh_save_regp_x x29, 48 stp x29, x30, [sp, #16] .seh_save_regp x29, 16 add x29, sp, #0 .seh_add_fp 0 str d8, [sp, #32] .seh_save_freg d8, 32 .seh_endprologue nop .seh_startepilogue mov sp, x29 .seh_set_fp ldp x29, x30, [sp, #16] .seh_save_fplr 16 ldp x29, x30, [sp, #-48]! .seh_save_fplr_x 48 ldp x21, x22, [sp, #16] .seh_save_next ldp x19, x20, [sp], #32 .seh_save_regp_x x19, 32 ldp x20, x21, [sp, #16] .seh_save_regp x20, 16 add sp, sp, #48 .seh_stackalloc 48 .seh_endepilogue ret .seh_endproc // Test a perfectly matching epilog with no offset. .seh_proc packed2 packed2: sub sp, sp, #48 .seh_stackalloc 48 stp x29, lr, [sp, #-32]! .seh_save_fplr_x 32 .seh_endprologue nop .seh_startepilogue ldp x29, lr, [sp], #32 .seh_save_fplr_x 32 add sp, sp, #48 .seh_stackalloc 48 .seh_endepilogue ret .seh_endproc .seh_proc nonpacked1 nonpacked1: sub sp, sp, #48 .seh_stackalloc 48 .seh_endprologue nop .seh_startepilogue add sp, sp, #48 .seh_stackalloc 48 .seh_endepilogue // This epilogue isn't packed with the prologue, as it doesn't align with // the end of the function (one extra nop before the ret). nop ret .seh_endproc .seh_proc nonpacked2 nonpacked2: sub sp, sp, #48 .seh_stackalloc 48 sub sp, sp, #32 .seh_stackalloc 32 .seh_endprologue nop .seh_startepilogue // Not packed; the epilogue mismatches at the second opcode. add sp, sp, #16 .seh_stackalloc 16 add sp, sp, #48 .seh_stackalloc 48 .seh_endepilogue ret .seh_endproc .seh_proc nonpacked3 nonpacked3: sub sp, sp, #48 .seh_stackalloc 48 sub sp, sp, #32 .seh_stackalloc 32 .seh_endprologue nop .seh_startepilogue // Not packed; the epilogue is longer than the prologue. mov sp, x29 .seh_set_fp add sp, sp, #32 .seh_stackalloc 32 add sp, sp, #48 .seh_stackalloc 48 .seh_endepilogue ret .seh_endproc