1# RUN: llc -o - %s -mtriple=aarch64-windows -start-after=prologepilog -filetype=obj  \
2# RUN:   | llvm-readobj --unwind | FileCheck %s
3# RUN: llc -o - %s -mtriple=aarch64-windows -run-pass=aarch64-ldst-opt \
4# RUN:   | FileCheck %s --check-prefix=CHECK-LDSTOPT
5# This test case checks the basic validity of the .xdata section.  It's
6# documented at:
7# https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
8
9# We expect to see the following in the .xdata section:
10
11# CHECK: 	 ExceptionData {
12# CHECK-NEXT:      FunctionLength: 96
13# CHECK-NEXT:      Version: 0
14# CHECK-NEXT:      ExceptionData: No
15# CHECK-NEXT:      EpiloguePacked: No
16# CHECK-NEXT:      EpilogueScopes: 1
17# CHECK-NEXT:      ByteCodeLength: 28
18# CHECK-NEXT:      Prologue [
19# CHECK-NEXT:        0xc808              ; stp x19, x20, [sp, #64]
20# CHECK-NEXT:        0xd0c7              ; str x22, [sp, #56]
21# CHECK-NEXT:        0xd086              ; str x21, [sp, #48]
22# CHECK-NEXT:        0xc904              ; stp x23, x24, [sp, #32]
23# CHECK-NEXT:        0xc982              ; stp x25, x26, [sp, #16]
24# CHECK-NEXT:        0xce09              ; stp x27, x28, [sp, #-80]!
25# CHECK-NEXT:        0xe4                ; end
26# CHECK-NEXT:      ]
27# CHECK-NEXT:      EpilogueScopes [
28# CHECK-NEXT:        EpilogueScope {
29# CHECK-NEXT:          StartOffset: 16
30# CHECK-NEXT:          EpilogueStartIndex: 13
31# CHECK-NEXT:          Opcodes [
32# CHECK-NEXT:            0xc808              ; ldp x19, x20, [sp, #64]
33# CHECK-NEXT:            0xd086              ; ldr x21, [sp, #48]
34# CHECK-NEXT:            0xe3                ; nop
35# CHECK-NEXT:            0xd0c7              ; ldr x22, [sp, #56]
36# CHECK-NEXT:            0xc904              ; ldp x23, x24, [sp, #32]
37# CHECK-NEXT:            0xc982              ; ldp x25, x26, [sp, #16]
38# CHECK-NEXT:            0xce09              ; ldp x27, x28, [sp], #80
39# CHECK-NEXT:            0xe4                ; end
40# CHECK-NEXT:          ]
41# CHECK-NEXT:        }
42# CHECK-NEXT:      ]
43# CHECK-NEXT:    }
44
45# Check that the load-store optimizer does not merge the two
46# callee-saved stores in the prologue.
47# CHECK-LDSTOPT: name: test
48# CHECK-LDSTOPT: frame-setup STRXui killed $x21, $sp, 6
49# CHECK-LDSTOPT: frame-setup STRXui killed $x22, $sp, 7
50...
51---
52name:            test
53alignment:       4
54tracksRegLiveness: true
55hasWinCFI: true
56liveins:
57  - { reg: '$w0' }
58frameInfo:
59  stackSize:       80
60  maxAlignment:    8
61  maxCallFrameSize: 0
62  hasOpaqueSPAdjustment: true
63stack:
64  - { id: 0, type: spill-slot, offset: -8, size: 8, alignment: 8, stack-id: default,
65      callee-saved-register: '$x19' }
66  - { id: 1, type: spill-slot, offset: -16, size: 8, alignment: 8, stack-id: default,
67      callee-saved-register: '$x20' }
68  - { id: 2, type: spill-slot, offset: -24, size: 8, alignment: 8, stack-id: default,
69      callee-saved-register: '$x21' }
70  - { id: 3, type: spill-slot, offset: -32, size: 8, alignment: 8, stack-id: default,
71      callee-saved-register: '$x22' }
72  - { id: 4, type: spill-slot, offset: -40, size: 8, alignment: 8, stack-id: default,
73      callee-saved-register: '$x23' }
74  - { id: 5, type: spill-slot, offset: -48, size: 8, alignment: 8, stack-id: default,
75      callee-saved-register: '$x24' }
76  - { id: 6, type: spill-slot, offset: -56, size: 8, alignment: 8, stack-id: default,
77      callee-saved-register: '$x25' }
78  - { id: 7, type: spill-slot, offset: -64, size: 8, alignment: 8, stack-id: default,
79      callee-saved-register: '$x26' }
80  - { id: 8, type: spill-slot, offset: -72, size: 8, alignment: 8, stack-id: default,
81      callee-saved-register: '$x27' }
82  - { id: 9, type: spill-slot, offset: -80, size: 8, alignment: 8, stack-id: default,
83      callee-saved-register: '$x28' }
84body:             |
85  bb.0.entry:
86    liveins: $x0, $x1, $x27, $x28, $x25, $x26, $x23, $x24, $x21, $x22, $x19, $x20
87    early-clobber $sp = frame-setup STPXpre killed $x27, killed $x28, $sp, -10 :: (store 8 into %stack.8), (store 8 into %stack.9)
88    frame-setup SEH_SaveRegP_X 27, 28, -80
89    frame-setup STPXi killed $x25, killed $x26, $sp, 2 :: (store 8 into %stack.6), (store 8 into %stack.7)
90    frame-setup SEH_SaveRegP 25, 26, 16
91    frame-setup STPXi killed $x23, killed $x24, $sp, 4 :: (store 8 into %stack.4), (store 8 into %stack.5)
92    frame-setup SEH_SaveRegP 23, 24, 32
93    frame-setup STRXui killed $x21, $sp, 6 :: (store 8 into %stack.2)
94    frame-setup SEH_SaveReg 21, 48
95    frame-setup STRXui killed $x22, $sp, 7 :: (store 8 into %stack.3)
96    frame-setup SEH_SaveReg 22, 56
97    frame-setup STPXi killed $x19, killed $x20, $sp, 8 :: (store 8 into %stack.0), (store 8 into %stack.1)
98    frame-setup SEH_SaveRegP 19, 20, 64
99    frame-setup SEH_PrologEnd
100    $x19 = ADDXrr $x0, killed $x1
101    $x20 = ADDXrr $x19, killed $x0
102    $x21 = ADDXrr $x20, killed $x19
103    $x22 = ADDXrr $x21, killed $x20
104    $x23 = ADDXrr $x22, killed $x21
105    $x24 = ADDXrr $x23, killed $x22
106    $x25 = ADDXrr $x24, killed $x23
107    $x26 = ADDXrr $x25, killed $x24
108    $x27 = ADDXrr $x26, killed $x25
109    $x28 = ADDXrr $x27, killed $x26
110    frame-destroy SEH_EpilogStart
111    $x19, $x20 = frame-destroy LDPXi $sp, 8 :: (load 8 from %stack.0), (load 8 from %stack.1)
112    frame-destroy SEH_SaveRegP 19, 20, 64
113    $x21 = frame-destroy LDRXui $sp, 6 :: (load 8 from %stack.2)
114    frame-destroy SEH_SaveReg 21, 48
115    $x0 = COPY $x28
116    frame-destroy SEH_Nop
117    $x21 = frame-destroy LDRXui $sp, 6 :: (load 8 from %stack.2)
118    frame-destroy SEH_SaveReg 22, 56
119    $x23, $x24 = frame-destroy LDPXi $sp, 4 :: (load 8 from %stack.4), (load 8 from %stack.5)
120    frame-destroy SEH_SaveRegP 23, 24, 32
121    $x25, $x26 = frame-destroy LDPXi $sp, 2 :: (load 8 from %stack.6), (load 8 from %stack.7)
122    frame-destroy SEH_SaveRegP 25, 26, 16
123    early-clobber $sp, $x27, $x28 = frame-destroy LDPXpost $sp, 10 :: (load 8 from %stack.8), (load 8 from %stack.9)
124    frame-destroy SEH_SaveRegP_X 27, 28, -80
125    frame-destroy SEH_EpilogEnd
126    RET_ReallyLR implicit $x0
127
128...
129