220 lines · plain
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.o4// RUN: llvm-readobj -u %t.o | FileCheck %s5 6// CHECK: UnwindInformation [7// CHECK-NEXT: RuntimeFunction {8// CHECK-NEXT: Function: func9// CHECK-NEXT: ExceptionRecord: .xdata10// CHECK-NEXT: ExceptionData {11// CHECK-NEXT: FunctionLength:12// CHECK-NEXT: Version:13// CHECK-NEXT: ExceptionData:14// CHECK-NEXT: EpiloguePacked: Yes15// CHECK-NEXT: EpilogueOffset: 216// CHECK-NEXT: ByteCodeLength:17// CHECK-NEXT: Prologue [18// CHECK-NEXT: 0xdc04 ; str d8, [sp, #32]19// CHECK-NEXT: 0xe1 ; mov fp, sp20// CHECK-NEXT: 0x42 ; stp x29, x30, [sp, #16]21// CHECK-NEXT: 0x85 ; stp x29, x30, [sp, #-48]!22// CHECK-NEXT: 0xe6 ; save next23// CHECK-NEXT: 0x24 ; stp x19, x20, [sp, #-32]!24// CHECK-NEXT: 0xc842 ; stp x20, x21, [sp, #16]25// CHECK-NEXT: 0x03 ; sub sp, #4826// CHECK-NEXT: 0xe4 ; end27// CHECK-NEXT: ]28// CHECK-NEXT: Epilogue [29// CHECK-NEXT: 0xe1 ; mov sp, fp30// CHECK-NEXT: 0x42 ; ldp x29, x30, [sp, #16]31// CHECK-NEXT: 0x85 ; ldp x29, x30, [sp], #4832// CHECK-NEXT: 0xe6 ; restore next33// CHECK-NEXT: 0x24 ; ldp x19, x20, [sp], #3234// CHECK-NEXT: 0xc842 ; ldp x20, x21, [sp, #16]35// CHECK-NEXT: 0x03 ; add sp, #4836// CHECK-NEXT: 0xe4 ; end37// CHECK-NEXT: ]38// CHECK-NEXT: }39// CHECK-NEXT: }40// CHECK: RuntimeFunction {41// CHECK-NEXT: Function: packed242// CHECK-NEXT: ExceptionRecord:43// CHECK-NEXT: ExceptionData {44// CHECK: ExceptionData:45// CHECK-NEXT: EpiloguePacked: Yes46// CHECK-NEXT: EpilogueOffset: 047// CHECK-NEXT: ByteCodeLength: 448// CHECK-NEXT: Prologue [49// CHECK-NEXT: 0x83 ; stp x29, x30, [sp, #-32]!50// CHECK-NEXT: 0x03 ; sub sp, #4851// CHECK-NEXT: 0xe4 ; end52// CHECK-NEXT: ]53// CHECK: RuntimeFunction {54// CHECK-NEXT: Function: nonpacked155// CHECK-NEXT: ExceptionRecord:56// CHECK-NEXT: ExceptionData {57// CHECK: ExceptionData:58// CHECK-NEXT: EpiloguePacked: No59// CHECK: RuntimeFunction {60// CHECK-NEXT: Function: nonshared261// CHECK-NEXT: ExceptionRecord:62// CHECK-NEXT: ExceptionData {63// CHECK: ExceptionData:64// CHECK-NEXT: EpiloguePacked: Yes65// CHECK-NEXT: EpilogueOffset: 366// CHECK-NEXT: ByteCodeLength: 867// CHECK-NEXT: Prologue [68// CHECK-NEXT: 0x02 ; sub sp, #3269// CHECK-NEXT: 0x03 ; sub sp, #4870// CHECK-NEXT: 0xe4 ; end71// CHECK-NEXT: ]72// CHECK-NEXT: Epilogue [73// CHECK-NEXT: 0x01 ; add sp, #1674// CHECK-NEXT: 0x03 ; add sp, #4875// CHECK-NEXT: 0xe4 ; end76// CHECK-NEXT: ]77// CHECK: RuntimeFunction {78// CHECK-NEXT: Function: nonshared379// CHECK-NEXT: ExceptionRecord:80// CHECK-NEXT: ExceptionData {81// CHECK: ExceptionData:82// CHECK-NEXT: EpiloguePacked: Yes83// CHECK-NEXT: EpilogueOffset: 384// CHECK-NEXT: ByteCodeLength: 885// CHECK-NEXT: Prologue [86// CHECK-NEXT: 0x02 ; sub sp, #3287// CHECK-NEXT: 0x03 ; sub sp, #4888// CHECK-NEXT: 0xe4 ; end89// CHECK-NEXT: ]90// CHECK-NEXT: Epilogue [91// CHECK-NEXT: 0xe1 ; mov sp, fp92// CHECK-NEXT: 0x02 ; add sp, #3293// CHECK-NEXT: 0x03 ; add sp, #4894// CHECK-NEXT: 0xe4 ; end95// CHECK-NEXT: ]96 97 .text98 .globl func99 .seh_proc func100func:101 sub sp, sp, #48102 .seh_stackalloc 48103 // Check that canonical opcode forms (r19r20_x, fplr, fplr_x, save_next,104 // set_fp) are treated as a match even if one (in prologue or epilogue)105 // was simplified from the more generic opcodes.106 stp x20, x21, [sp, #16]107 .seh_save_regp x20, 16108 stp x19, x20, [sp, #-32]!109 .seh_save_r19r20_x 32110 stp x21, x22, [sp, #16]111 .seh_save_regp x21, 16112 stp x29, x30, [sp, #-48]!113 .seh_save_regp_x x29, 48114 stp x29, x30, [sp, #16]115 .seh_save_regp x29, 16116 add x29, sp, #0117 .seh_add_fp 0118 str d8, [sp, #32]119 .seh_save_freg d8, 32120 .seh_endprologue121 122 nop123 124 .seh_startepilogue125 mov sp, x29126 .seh_set_fp127 ldp x29, x30, [sp, #16]128 .seh_save_fplr 16129 ldp x29, x30, [sp, #-48]!130 .seh_save_fplr_x 48131 ldp x21, x22, [sp, #16]132 .seh_save_next133 ldp x19, x20, [sp], #32134 .seh_save_regp_x x19, 32135 ldp x20, x21, [sp, #16]136 .seh_save_regp x20, 16137 add sp, sp, #48138 .seh_stackalloc 48139 .seh_endepilogue140 ret141 .seh_endproc142 143 144 // Test a perfectly matching epilog with no offset.145 .seh_proc packed2146packed2:147 sub sp, sp, #48148 .seh_stackalloc 48149 stp x29, lr, [sp, #-32]!150 .seh_save_fplr_x 32151 .seh_endprologue152 nop153 .seh_startepilogue154 ldp x29, lr, [sp], #32155 .seh_save_fplr_x 32156 add sp, sp, #48157 .seh_stackalloc 48158 .seh_endepilogue159 ret160 .seh_endproc161 162 163 .seh_proc nonpacked1164nonpacked1:165 sub sp, sp, #48166 .seh_stackalloc 48167 .seh_endprologue168 169 nop170 .seh_startepilogue171 add sp, sp, #48172 .seh_stackalloc 48173 .seh_endepilogue174 // This epilogue isn't packed with the prologue, as it doesn't align with175 // the end of the function (one extra nop before the ret).176 nop177 ret178 .seh_endproc179 180 181 .seh_proc nonshared2182nonshared2:183 sub sp, sp, #48184 .seh_stackalloc 48185 sub sp, sp, #32186 .seh_stackalloc 32187 .seh_endprologue188 189 nop190 .seh_startepilogue191 // Not shared; the epilogue mismatches at the second opcode.192 add sp, sp, #16193 .seh_stackalloc 16194 add sp, sp, #48195 .seh_stackalloc 48196 .seh_endepilogue197 ret198 .seh_endproc199 200 .seh_proc nonshared3201nonshared3:202 sub sp, sp, #48203 .seh_stackalloc 48204 sub sp, sp, #32205 .seh_stackalloc 32206 .seh_endprologue207 208 nop209 .seh_startepilogue210 // Not shared; the epilogue is longer than the prologue.211 mov sp, x29212 .seh_set_fp213 add sp, sp, #32214 .seh_stackalloc 32215 add sp, sp, #48216 .seh_stackalloc 48217 .seh_endepilogue218 ret219 .seh_endproc220