1// This test checks that the unwinding opcodes are remapped to more
2// efficient ones where possible.
3
4// RUN: llvm-mc -triple aarch64-pc-win32 -filetype=obj %s -o %t.o
5// RUN: llvm-readobj -u %t.o | FileCheck %s
6
7// CHECK:      UnwindInformation [
8// CHECK-NEXT:   RuntimeFunction {
9// CHECK-NEXT:     Function: func
10// CHECK-NEXT:     ExceptionRecord: .xdata
11// CHECK-NEXT:     ExceptionData {
12// CHECK:            Prologue [
13// CHECK-NEXT:         0xd882              ; stp d10, d11, [sp, #16]
14// CHECK-NEXT:         0xda07              ; stp d8, d9, [sp, #-64]!
15// CHECK-NEXT:         0xe6                ; save next
16// CHECK-NEXT:         0x28                ; stp x19, x20, [sp, #-64]!
17// CHECK-NEXT:         0xca49              ; stp x28, x29, [sp, #72]
18// CHECK-NEXT:         0xe6                ; save next
19// CHECK-NEXT:         0xe6                ; save next
20// CHECK-NEXT:         0xe6                ; save next
21// CHECK-NEXT:         0xcc47              ; stp x20, x21, [sp, #-64]!
22// CHECK-NEXT:         0x42                ; stp x29, x30, [sp, #16]
23// CHECK-NEXT:         0xca02              ; stp x27, x28, [sp, #16]
24// CHECK-NEXT:         0x83                ; stp x29, x30, [sp, #-32]!
25// CHECK-NEXT:         0xce03              ; stp x27, x28, [sp, #-32]!
26// CHECK-NEXT:         0xe1                ; mov fp, sp
27// CHECK-NEXT:         0xe201              ; add fp, sp, #8
28// CHECK-NEXT:         0xe4                ; end
29// CHECK-NEXT:       ]
30// CHECK-NEXT:       Epilogue [
31// CHECK-NEXT:         0xc904              ; ldp x23, x24, [sp, #32]
32// CHECK-NEXT:         0xe6                ; restore next
33// CHECK-NEXT:         0xcc83              ; ldp x21, x22, [sp], #32
34// CHECK-NEXT:         0x24                ; ldp x19, x20, [sp], #32
35// CHECK-NEXT:         0xcc1f              ; ldp x19, x20, [sp], #256
36// CHECK-NEXT:         0xe4                ; end
37// CHECK-NEXT:       ]
38// CHECK-NEXT:     }
39// CHECK-NEXT:   }
40// CHECK-NEXT: ]
41
42
43    .text
44    .globl func
45    .seh_proc func
46func:
47    add x29, sp, #8
48    .seh_add_fp 8
49    add x29, sp, #0
50    .seh_add_fp 0
51
52    stp x27, x28, [sp, #-32]!
53    .seh_save_regp_x x27, 32
54    stp x29, x30, [sp, #-32]!
55    .seh_save_regp_x x29, 32
56
57    stp x27, x28, [sp, #16]
58    .seh_save_regp x27, 16
59    stp x29, x30, [sp, #16]
60    .seh_save_regp x29, 16
61
62    stp x20, x21, [sp, #-64]!
63    .seh_save_regp_x x20, 64
64    stp x22, x23, [sp, #16]
65    .seh_save_regp x22, 16
66    stp x24, x25, [sp, #32]
67    .seh_save_next
68    stp x26, x27, [sp, #48]
69    .seh_save_regp x26, 48
70    stp x28, x29, [sp, #72]
71    .seh_save_regp x28, 72
72
73    stp x19, x20, [sp, #-64]!
74    .seh_save_r19r20_x 64
75    stp x21, x22, [sp, #16]
76    .seh_save_regp x21, 16
77
78    stp d8,  d9,  [sp, #-64]!
79    .seh_save_fregp_x d8, 64
80    stp d10, d11, [sp, #16]
81    // This is intentionally not converted into a save_next, to avoid
82    // bugs in the windows unwinder.
83    .seh_save_fregp d10, 16
84
85    .seh_endprologue
86
87    nop
88
89    .seh_startepilogue
90    ldp x27, x28, [sp, #32]
91    .seh_save_regp x23, 32
92    ldp x23, x24, [sp, #16]
93    .seh_save_regp x23, 16
94    ldp x21, x22, [sp], #32
95    .seh_save_regp_x x21, 32
96    ldp x19, x20, [sp], #32
97    .seh_save_regp_x x19, 32
98    ldp x19, x20, [sp], #256
99    .seh_save_regp_x x19, 256
100    .seh_endepilogue
101    ret
102    .seh_endproc
103