1// This test checks that the epilogue is packed where possible. 2 3// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o 4// RUN: llvm-readobj -u %t.o | FileCheck %s 5 6// CHECK: UnwindInformation [ 7// CHECK-NEXT: RuntimeFunction { 8// CHECK-NEXT: Function: func 9// CHECK-NEXT: ExceptionRecord: .xdata 10// CHECK-NEXT: ExceptionData { 11// CHECK-NEXT: FunctionLength: 12// CHECK-NEXT: Version: 13// CHECK-NEXT: ExceptionData: 14// CHECK-NEXT: EpiloguePacked: Yes 15// CHECK-NEXT: EpilogueOffset: 2 16// CHECK-NEXT: ByteCodeLength: 17// CHECK-NEXT: Prologue [ 18// CHECK-NEXT: 0xdc04 ; str d8, [sp, #32] 19// CHECK-NEXT: 0xe1 ; mov fp, sp 20// CHECK-NEXT: 0x42 ; stp x29, x30, [sp, #16] 21// CHECK-NEXT: 0x85 ; stp x29, x30, [sp, #-48]! 22// CHECK-NEXT: 0xe6 ; save next 23// CHECK-NEXT: 0x24 ; stp x19, x20, [sp, #-32]! 24// CHECK-NEXT: 0xc842 ; stp x20, x21, [sp, #16] 25// CHECK-NEXT: 0x03 ; sub sp, #48 26// CHECK-NEXT: 0xe4 ; end 27// CHECK-NEXT: ] 28// CHECK-NEXT: Epilogue [ 29// CHECK-NEXT: 0xe1 ; mov sp, fp 30// CHECK-NEXT: 0x42 ; ldp x29, x30, [sp, #16] 31// CHECK-NEXT: 0x85 ; ldp x29, x30, [sp], #48 32// CHECK-NEXT: 0xe6 ; restore next 33// CHECK-NEXT: 0x24 ; ldp x19, x20, [sp], #32 34// CHECK-NEXT: 0xc842 ; ldp x20, x21, [sp, #16] 35// CHECK-NEXT: 0x03 ; add sp, #48 36// CHECK-NEXT: 0xe4 ; end 37// CHECK-NEXT: ] 38// CHECK-NEXT: } 39// CHECK-NEXT: } 40// CHECK: RuntimeFunction { 41// CHECK-NEXT: Function: packed2 42// CHECK-NEXT: ExceptionRecord: 43// CHECK-NEXT: ExceptionData { 44// CHECK: ExceptionData: 45// CHECK-NEXT: EpiloguePacked: Yes 46// CHECK: RuntimeFunction { 47// CHECK-NEXT: Function: nonpacked1 48// CHECK-NEXT: ExceptionRecord: 49// CHECK-NEXT: ExceptionData { 50// CHECK: ExceptionData: 51// CHECK-NEXT: EpiloguePacked: No 52// CHECK: RuntimeFunction { 53// CHECK-NEXT: Function: nonpacked2 54// CHECK-NEXT: ExceptionRecord: 55// CHECK-NEXT: ExceptionData { 56// CHECK: ExceptionData: 57// CHECK-NEXT: EpiloguePacked: No 58// CHECK: RuntimeFunction { 59// CHECK-NEXT: Function: nonpacked3 60// CHECK-NEXT: ExceptionRecord: 61// CHECK-NEXT: ExceptionData { 62// CHECK: ExceptionData: 63// CHECK-NEXT: EpiloguePacked: No 64 65 .text 66 .globl func 67 .seh_proc func 68func: 69 sub sp, sp, #48 70 .seh_stackalloc 48 71 // Check that canonical opcode forms (r19r20_x, fplr, fplr_x, save_next, 72 // set_fp) are treated as a match even if one (in prologue or epilogue) 73 // was simplified from the more generic opcodes. 74 stp x20, x21, [sp, #16] 75 .seh_save_regp x20, 16 76 stp x19, x20, [sp, #-32]! 77 .seh_save_r19r20_x 32 78 stp x21, x22, [sp, #16] 79 .seh_save_regp x21, 16 80 stp x29, x30, [sp, #-48]! 81 .seh_save_regp_x x29, 48 82 stp x29, x30, [sp, #16] 83 .seh_save_regp x29, 16 84 add x29, sp, #0 85 .seh_add_fp 0 86 str d8, [sp, #32] 87 .seh_save_freg d8, 32 88 .seh_endprologue 89 90 nop 91 92 .seh_startepilogue 93 mov sp, x29 94 .seh_set_fp 95 ldp x29, x30, [sp, #16] 96 .seh_save_fplr 16 97 ldp x29, x30, [sp, #-48]! 98 .seh_save_fplr_x 48 99 ldp x21, x22, [sp, #16] 100 .seh_save_next 101 ldp x19, x20, [sp], #32 102 .seh_save_regp_x x19, 32 103 ldp x20, x21, [sp, #16] 104 .seh_save_regp x20, 16 105 add sp, sp, #48 106 .seh_stackalloc 48 107 .seh_endepilogue 108 ret 109 .seh_endproc 110 111 112 // Test a perfectly matching epilog with no offset. 113 .seh_proc packed2 114packed2: 115 sub sp, sp, #48 116 .seh_stackalloc 48 117 stp x29, lr, [sp, #-32]! 118 .seh_save_fplr_x 32 119 .seh_endprologue 120 nop 121 .seh_startepilogue 122 ldp x29, lr, [sp], #32 123 .seh_save_fplr_x 32 124 add sp, sp, #48 125 .seh_stackalloc 48 126 .seh_endepilogue 127 ret 128 .seh_endproc 129 130 131 .seh_proc nonpacked1 132nonpacked1: 133 sub sp, sp, #48 134 .seh_stackalloc 48 135 .seh_endprologue 136 137 nop 138 .seh_startepilogue 139 add sp, sp, #48 140 .seh_stackalloc 48 141 .seh_endepilogue 142 // This epilogue isn't packed with the prologue, as it doesn't align with 143 // the end of the function (one extra nop before the ret). 144 nop 145 ret 146 .seh_endproc 147 148 149 .seh_proc nonpacked2 150nonpacked2: 151 sub sp, sp, #48 152 .seh_stackalloc 48 153 sub sp, sp, #32 154 .seh_stackalloc 32 155 .seh_endprologue 156 157 nop 158 .seh_startepilogue 159 // Not packed; the epilogue mismatches at the second opcode. 160 add sp, sp, #16 161 .seh_stackalloc 16 162 add sp, sp, #48 163 .seh_stackalloc 48 164 .seh_endepilogue 165 ret 166 .seh_endproc 167 168 .seh_proc nonpacked3 169nonpacked3: 170 sub sp, sp, #48 171 .seh_stackalloc 48 172 sub sp, sp, #32 173 .seh_stackalloc 32 174 .seh_endprologue 175 176 nop 177 .seh_startepilogue 178 // Not packed; the epilogue is longer than the prologue. 179 mov sp, x29 180 .seh_set_fp 181 add sp, sp, #32 182 .seh_stackalloc 32 183 add sp, sp, #48 184 .seh_stackalloc 48 185 .seh_endepilogue 186 ret 187 .seh_endproc 188