190 lines · plain
1// This test checks various cases around sharing opcodes between epilogue and prologue with more than one epilogue.2 3// RUN: llvm-mc -triple thumbv7-pc-win32 -filetype=obj %s | llvm-readobj -u - | FileCheck %s4 5// CHECK: RuntimeFunction {6// CHECK-NEXT: Function: func17// CHECK-NEXT: ExceptionRecord:8// CHECK-NEXT: ExceptionData {9// CHECK-NEXT: FunctionLength:10// CHECK-NEXT: Version:11// CHECK-NEXT: ExceptionData:12// CHECK-NEXT: EpiloguePacked: No13// CHECK-NEXT: Fragment:14// CHECK-NEXT: EpilogueScopes: 315// CHECK-NEXT: ByteCodeLength: 1216// 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: ]21// CHECK-NEXT: EpilogueScopes [22// CHECK-NEXT: EpilogueScope {23// CHECK-NEXT: StartOffset: 624// CHECK-NEXT: Condition: 1425// CHECK-NEXT: EpilogueStartIndex: 626// CHECK-NEXT: Opcodes [27// CHECK-NEXT: 0x08 ; add sp, #(8 * 4)28// CHECK-NEXT: 0xfd ; bx <reg>29// CHECK-NEXT: ]30// CHECK-NEXT: }31// CHECK-NEXT: EpilogueScope {32// CHECK-NEXT: StartOffset: 933// CHECK-NEXT: Condition: 1434// CHECK-NEXT: EpilogueStartIndex: 835// CHECK-NEXT: Opcodes [36// CHECK-NEXT: 0x10 ; add sp, #(16 * 4)37// CHECK-NEXT: 0xfd ; bx <reg>38// CHECK-NEXT: ]39// CHECK-NEXT: }40// CHECK-NEXT: EpilogueScope {41// CHECK-NEXT: StartOffset: 1342// CHECK-NEXT: Condition: 1043// CHECK-NEXT: EpilogueStartIndex: 644// CHECK-NEXT: Opcodes [45// CHECK-NEXT: 0x08 ; add sp, #(8 * 4)46// CHECK-NEXT: 0xfd ; bx <reg>47// CHECK-NEXT: ]48// CHECK-NEXT: }49// CHECK-NEXT: ]50// CHECK-NEXT: }51// CHECK-NEXT: }52// CHECK-NEXT: RuntimeFunction {53// CHECK-NEXT: Function: func254// CHECK-NEXT: ExceptionRecord:55// CHECK-NEXT: ExceptionData {56// CHECK-NEXT: FunctionLength:57// CHECK-NEXT: Version:58// CHECK-NEXT: ExceptionData:59// CHECK-NEXT: EpiloguePacked: No60// CHECK-NEXT: Fragment:61// CHECK-NEXT: EpilogueScopes: 362// CHECK-NEXT: ByteCodeLength: 1263// CHECK-NEXT: Prologue [64// CHECK-NEXT: 0xf5 0x15 ; vpush {d1-d5}65// CHECK-NEXT: 0x05 ; sub sp, #(5 * 4)66// CHECK-NEXT: 0xa0 0xf0 ; push.w {r4-r7, lr}67// CHECK-NEXT: 0xfe ; b.w <target>68// CHECK-NEXT: ]69// CHECK-NEXT: EpilogueScopes [70// CHECK-NEXT: EpilogueScope {71// CHECK-NEXT: StartOffset: 672// CHECK-NEXT: Condition: 1473// CHECK-NEXT: EpilogueStartIndex: 274// CHECK-NEXT: Opcodes [75// CHECK-NEXT: 0x05 ; add sp, #(5 * 4)76// CHECK-NEXT: 0xa0 0xf0 ; pop.w {r4-r7, pc}77// CHECK-NEXT: 0xfe ; b.w <target>78// CHECK-NEXT: ]79// CHECK-NEXT: }80// CHECK-NEXT: EpilogueScope {81// CHECK-NEXT: StartOffset: 1182// CHECK-NEXT: Condition: 1483// CHECK-NEXT: EpilogueStartIndex: 384// CHECK-NEXT: Opcodes [85// CHECK-NEXT: 0xa0 0xf0 ; pop.w {r4-r7, pc}86// CHECK-NEXT: 0xfe ; b.w <target>87// CHECK-NEXT: ]88// CHECK-NEXT: }89// CHECK-NEXT: EpilogueScope {90// CHECK-NEXT: StartOffset: 1591// CHECK-NEXT: Condition: 1492// CHECK-NEXT: EpilogueStartIndex: 693// CHECK-NEXT: Opcodes [94// CHECK-NEXT: 0xa0 0xf0 ; pop.w {r4-r7, pc}95// CHECK-NEXT: 0xfd ; bx <reg>96// CHECK-NEXT: ]97// CHECK-NEXT: }98// CHECK-NEXT: ]99// CHECK-NEXT: }100// CHECK-NEXT: }101 102 .text103 .syntax unified104 105 .seh_proc func1106func1:107 push.w {r4-r7,lr}108 .seh_save_regs_w {r4-r7,lr}109 sub sp, sp, #20110 .seh_stackalloc 20111 vpush {d1-d5}112 .seh_save_fregs {d1-d5}113 .seh_endprologue114 nop115 116 // Entirely different epilogue; can't be shared with the prologue.117 .seh_startepilogue118 add sp, sp, #32119 .seh_stackalloc 32120 bx lr121 .seh_nop122 .seh_endepilogue123 124 nop125 126 // Also a differing epilogue.127 .seh_startepilogue128 add sp, sp, #64129 .seh_stackalloc 64130 bx lr131 .seh_nop132 .seh_endepilogue133 134 nop135 136 // Epilogue matches the first one; will reuse that epilogue's opcodes,137 // even if they differ in conditionality.138 itt ge139 .seh_startepilogue_cond ge140 addge sp, sp, #32141 .seh_stackalloc 32142 bxge lr143 .seh_nop144 .seh_endepilogue145 .seh_endproc146 147 .seh_proc func2148func2:149 push.w {r4-r7,lr}150 .seh_save_regs_w {r4-r7,lr}151 sub sp, sp, #20152 .seh_stackalloc 20153 vpush {d1-d5}154 .seh_save_fregs {d1-d5}155 .seh_endprologue156 157 nop158 159 .seh_startepilogue160 add sp, sp, #20161 .seh_stackalloc 20162 // As we're popping into lr instead of directly into pc, this pop163 // becomes a wide instruction. To match prologue vs epilogue, the164 // push in the prologue has been made wide too.165 pop.w {r4-r7,lr}166 .seh_save_regs_w {r4-r7,lr}167 b.w tailcall168 // Ending with a different end opcode, but can still be shared with169 // the prolog.170 .seh_nop_w171 .seh_endepilogue172 173 // Another epilogue, matching the end of the previous epilogue.174 .seh_startepilogue175 pop.w {r4-r7,lr}176 .seh_save_regs_w {r4-r7,lr}177 b.w tailcall178 .seh_nop_w179 .seh_endepilogue180 181 // This epilogue differs in the end opcode, and can't be shared with182 // the prologue.183 .seh_startepilogue184 pop.w {r4-r7,lr}185 .seh_save_regs_w {r4-r7,lr}186 bx lr187 .seh_nop188 .seh_endepilogue189 .seh_endproc190