1// This test checks various cases around sharing opcodes between epilogue and prologue 2 3// RUN: llvm-mc -triple thumbv7-pc-win32 -filetype=obj %s | llvm-readobj -u - | FileCheck %s 4 5// CHECK: RuntimeFunction { 6// CHECK-NEXT: Function: func1 7// CHECK-NEXT: ExceptionRecord: 8// CHECK-NEXT: ExceptionData { 9// CHECK-NEXT: FunctionLength: 10// CHECK-NEXT: Version: 11// CHECK-NEXT: ExceptionData: 12// CHECK-NEXT: EpiloguePacked: Yes 13// CHECK-NEXT: Fragment: No 14// CHECK-NEXT: EpilogueOffset: 2 15// CHECK-NEXT: ByteCodeLength: 16// CHECK-NEXT: Prologue [ 17// CHECK-NEXT: 0xf5 0x15 ; vpush {d1-d5} 18// CHECK-NEXT: 0x05 ; sub sp, #(5 * 4) 19// CHECK-NEXT: 0xa0 0xf0 ; push.w {r4-r7, lr} 20// CHECK-NEXT: 0xfe ; b.w <target> 21// CHECK-NEXT: ] 22// CHECK-NEXT: Epilogue [ 23// CHECK-NEXT: 0x05 ; add sp, #(5 * 4) 24// CHECK-NEXT: 0xa0 0xf0 ; pop.w {r4-r7, pc} 25// CHECK-NEXT: 0xfe ; b.w <target> 26// CHECK-NEXT: ] 27// CHECK-NEXT: } 28// CHECK-NEXT: } 29// CHECK-NEXT: RuntimeFunction { 30// CHECK-NEXT: Function: func2 31// CHECK-NEXT: ExceptionRecord: 32// CHECK-NEXT: ExceptionData { 33// CHECK-NEXT: FunctionLength: 34// CHECK-NEXT: Version: 35// CHECK-NEXT: ExceptionData: 36// CHECK-NEXT: EpiloguePacked: Yes 37// CHECK-NEXT: Fragment: No 38// CHECK-NEXT: EpilogueOffset: 0 39// CHECK-NEXT: ByteCodeLength: 4 40// CHECK-NEXT: Prologue [ 41// CHECK-NEXT: 0xd2 ; push {r4-r6} 42// CHECK-NEXT: 0x04 ; sub sp, #(4 * 4) 43// CHECK-NEXT: 0xfd ; bx <reg> 44// CHECK-NEXT: ] 45// CHECK-NEXT: } 46// CHECK-NEXT: } 47// CHECK-NEXT: RuntimeFunction { 48// CHECK-NEXT: Function: func3 49// CHECK-NEXT: ExceptionRecord: 50// CHECK-NEXT: ExceptionData { 51// CHECK-NEXT: FunctionLength: 52// CHECK-NEXT: Version: 53// CHECK-NEXT: ExceptionData: 54// CHECK-NEXT: EpiloguePacked: Yes 55// CHECK-NEXT: Fragment: No 56// CHECK-NEXT: EpilogueOffset: 0 57// CHECK-NEXT: ByteCodeLength: 4 58// CHECK-NEXT: Prologue [ 59// CHECK-NEXT: 0xe1 ; vpush {d8-d9} 60// CHECK-NEXT: 0xdf ; push.w {r4-r11, lr} 61// CHECK-NEXT: ] 62// CHECK-NEXT: } 63// CHECK-NEXT: } 64// CHECK-NEXT: RuntimeFunction { 65// CHECK-NEXT: Function: notshared1 66// CHECK-NEXT: ExceptionRecord: 67// CHECK-NEXT: ExceptionData { 68// CHECK-NEXT: FunctionLength: 69// CHECK-NEXT: Version: 70// CHECK-NEXT: ExceptionData: 71// CHECK-NEXT: EpiloguePacked: Yes 72// CHECK-NEXT: Fragment: 73// CHECK-NEXT: EpilogueOffset: 2 74// CHECK-NEXT: ByteCodeLength: 4 75// CHECK-NEXT: Prologue [ 76// CHECK-NEXT: 0xdf ; push.w {r4-r11, lr} 77// CHECK-NEXT: ] 78// CHECK-NEXT: Epilogue [ 79// CHECK-NEXT: 0xdb ; pop.w {r4-r11} 80// CHECK-NEXT: 0xfd ; bx <reg> 81// CHECK-NEXT: ] 82// CHECK: RuntimeFunction { 83// CHECK-NEXT: Function: notpacked2 84// CHECK-NEXT: ExceptionRecord: 85// CHECK-NEXT: ExceptionData { 86// CHECK-NEXT: FunctionLength: 87// CHECK-NEXT: Version: 88// CHECK-NEXT: ExceptionData: 89// CHECK-NEXT: EpiloguePacked: No 90// CHECK: RuntimeFunction { 91// CHECK-NEXT: Function: notpacked3 92// CHECK-NEXT: ExceptionRecord: 93// CHECK-NEXT: ExceptionData { 94// CHECK-NEXT: FunctionLength: 95// CHECK-NEXT: Version: 96// CHECK-NEXT: ExceptionData: 97// CHECK-NEXT: EpiloguePacked: No 98 99 .text 100 .syntax unified 101 .seh_proc func1 102func1: 103 push.w {r4-r7,lr} 104 .seh_save_regs_w {r4-r7,lr} 105 sub sp, sp, #20 106 .seh_stackalloc 20 107 vpush {d1-d5} 108 .seh_save_fregs {d1-d5} 109 .seh_endprologue 110 nop 111 .seh_startepilogue 112 add sp, sp, #20 113 .seh_stackalloc 20 114 // As we're popping into lr instead of directly into pc, this pop 115 // becomes a wide instruction. To match prologue vs epilogue, the 116 // push in the prologue has been made wide too. 117 pop.w {r4-r7,lr} 118 .seh_save_regs_w {r4-r7,lr} 119 b.w tailcall 120 .seh_nop_w 121 .seh_endepilogue 122 .seh_endproc 123 124 .seh_proc func2 125func2: 126 sub sp, sp, #16 127 .seh_stackalloc 16 128 push {r4-r6} 129 .seh_save_regs {r4-r6} 130 .seh_endprologue 131 nop 132 .seh_startepilogue 133 pop {r4-r6} 134 .seh_save_regs {r4-r6} 135 add sp, sp, #16 136 .seh_stackalloc 16 137 bx lr 138 .seh_nop 139 .seh_endepilogue 140 .seh_endproc 141 142 .seh_proc func3 143func3: 144 push {r4-r11,lr} 145 .seh_save_regs_w {r4-r11,lr} 146 vpush {d8-d9} 147 .seh_save_fregs {d8-d9} 148 .seh_endprologue 149 nop 150 .seh_startepilogue 151 vpop {d8-d9} 152 .seh_save_fregs {d8-d9} 153 pop {r4-r11,pc} 154 .seh_save_regs_w {r4-r11,pc} 155 .seh_endepilogue 156 .seh_endproc 157 158 .seh_proc notshared1 159notshared1: 160 push {r4-r11,lr} 161 .seh_save_regs_w {r4-r11,lr} 162 .seh_endprologue 163 nop 164 .seh_startepilogue 165 // Packed, but not shared as this opcode doesn't match the prolog 166 pop {r4-r11} 167 .seh_save_regs_w {r4-r11} 168 bx lr 169 .seh_nop 170 .seh_endepilogue 171 .seh_endproc 172 173 .seh_proc notpacked2 174notpacked2: 175 push {r4-r11} 176 .seh_save_regs_w {r4-r11} 177 vpush {d8-d9} 178 .seh_save_fregs {d8-d9} 179 .seh_endprologue 180 nop 181 .seh_startepilogue 182 vpop {d8-d9} 183 .seh_save_fregs {d8-d9} 184 pop {r4-r11} 185 .seh_save_regs_w {r4-r11} 186 bx lr 187 .seh_nop 188 .seh_endepilogue 189 // Not packed, as the epilog isn't at the end of the function 190 nop 191 .seh_endproc 192 193 .seh_proc notpacked3 194notpacked3: 195 push {r4-r11,lr} 196 .seh_save_regs_w {r4-r11,lr} 197 .seh_endprologue 198 nop 199 it ge 200 // Not packed, as the epilog is conditional 201 .seh_startepilogue_cond ge 202 popge {r4-r11,pc} 203 .seh_save_regs_w {r4-r11,pc} 204 .seh_endepilogue 205 .seh_endproc 206