1// This test checks that the SEH directives emit the correct unwind data.
2
3// TODO: Expected fail because SET_FPREG has a wrong offset.
4// XFAIL: *
5// RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -s -u | FileCheck %s
6
7// CHECK:      Sections [
8// CHECK:        Section {
9// CHECK:          Name: .text
10// CHECK:          RelocationCount: 0
11// CHECK:          Characteristics [
12// CHECK-NEXT:       ALIGN_4BYTES
13// CHECK-NEXT:       CNT_CODE
14// CHECK-NEXT:       MEM_EXECUTE
15// CHECK-NEXT:       MEM_READ
16// CHECK-NEXT:     ]
17// CHECK-NEXT:   }
18// CHECK:        Section {
19// CHECK:          Name: .xdata
20// CHECK:          RawDataSize: 52
21// CHECK:          RelocationCount: 4
22// CHECK:          Characteristics [
23// CHECK-NEXT:       ALIGN_4BYTES
24// CHECK-NEXT:       CNT_INITIALIZED_DATA
25// CHECK-NEXT:       MEM_READ
26// CHECK-NEXT:     ]
27// CHECK-NEXT:   }
28// CHECK:        Section {
29// CHECK:          Name: .pdata
30// CHECK:          RelocationCount: 9
31// CHECK:          Characteristics [
32// CHECK-NEXT:       ALIGN_4BYTES
33// CHECK-NEXT:       CNT_INITIALIZED_DATA
34// CHECK-NEXT:       MEM_READ
35// CHECK-NEXT:     ]
36// CHECK-NEXT:   }
37// CHECK-NEXT: ]
38
39// CHECK:      UnwindInformation [
40// CHECK-NEXT:   RuntimeFunction {
41// CHECK-NEXT:     StartAddress: [[CodeSect1:[^ ]+]] [[BeginDisp1:(\+0x[A-F0-9]+)?]]
42// CHECK-NEXT:     EndAddress: [[CodeSect1]] [[EndDisp1:(\+0x[A-F0-9]+)?]]
43// CHECK-NEXT:     UnwindInfoAddress:
44// CHECK-NEXT:     UnwindInfo {
45// CHECK-NEXT:       Version: 1
46// CHECK-NEXT:       Flags [
47// CHECK-NEXT:         ExceptionHandler
48// CHECK-NEXT:       ]
49// CHECK-NEXT:       PrologSize: 18
50// CHECK-NEXT:       FrameRegister: RBX
51// CHECK-NEXT:       FrameOffset: 0x0
52// CHECK-NEXT:       UnwindCodeCount: 8
53// CHECK-NEXT:       UnwindCodes [
54// CHECK-NEXT:         0x12: SET_FPREG reg=RBX, offset=0x0
55// CHECK-NEXT:         0x0F: PUSH_NONVOL reg=RBX
56// CHECK-NEXT:         0x0E: SAVE_XMM128 reg=XMM8, offset=0x0
57// CHECK-NEXT:         0x09: SAVE_NONVOL reg=RSI, offset=0x10
58// CHECK-NEXT:         0x04: ALLOC_SMALL size=24
59// CHECK-NEXT:         0x00: PUSH_MACHFRAME errcode=yes
60// CHECK-NEXT:       ]
61// CHECK-NEXT:       Handler: __C_specific_handler
62// CHECK-NEXT:     }
63// CHECK-NEXT:   }
64// CHECK-NEXT:   RuntimeFunction {
65// CHECK-NEXT:     StartAddress: [[CodeSect2:[^ ]+]] [[BeginDisp2:(\+0x[A-F0-9]+)?]]
66// CHECK-NEXT:     EndAddress: [[CodeSect2]] [[BeginDisp2:(\+0x[A-F0-9]+)?]]
67// CHECK-NEXT:     UnwindInfoAddress:
68// CHECK-NEXT:     UnwindInfo {
69// CHECK-NEXT:       Version: 1
70// CHECK-NEXT:       Flags [
71// CHECK-NEXT:         ChainInfo
72// CHECK-NEXT:       ]
73// CHECK-NEXT:       PrologSize: 0
74// CHECK-NEXT:       FrameRegister: -
75// CHECK-NEXT:       FrameOffset: -
76// CHECK-NEXT:       UnwindCodeCount: 0
77// CHECK-NEXT:       UnwindCodes [
78// CHECK-NEXT:       ]
79// CHECK-NEXT:       Chained {
80// CHECK-NEXT:         StartAddress: [[CodeSect1]] [[BeginDisp1]]
81// CHECK-NEXT:         EndAddress: [[CodeSect1]] [[EndDisp1]]
82// CHECK-NEXT:         UnwindInfoAddress:
83// CHECK-NEXT:       }
84// CHECK-NEXT:     }
85// CHECK-NEXT:   }
86// CHECK-NEXT:   RuntimeFunction {
87// CHECK-NEXT:     StartAddress: [[CodeSect3:[^ ]+]] [[BeginDisp3:(\+0x[A-F0-9]+)?]]
88// CHECK-NEXT:     EndAddress: [[CodeSect3]] [[BeginDisp3:(\+0x[A-F0-9]+)?]]
89// CHECK-NEXT:     UnwindInfoAddress:
90// CHECK-NEXT:     UnwindInfo {
91// CHECK-NEXT:       Version: 1
92// CHECK-NEXT:       Flags [
93// CHECK-NEXT:       ]
94// CHECK-NEXT:       PrologSize: 0
95// CHECK-NEXT:       FrameRegister: -
96// CHECK-NEXT:       FrameOffset: -
97// CHECK-NEXT:       UnwindCodeCount: 0
98// CHECK-NEXT:       UnwindCodes [
99// CHECK-NEXT:       ]
100// CHECK-NEXT:     }
101// CHECK-NEXT:   }
102// CHECK-NEXT: ]
103
104    .text
105    .globl func
106    .def func; .scl 2; .type 32; .endef
107    .seh_proc func
108func:
109    .seh_pushframe @code
110    subq $24, %rsp
111    .seh_stackalloc 24
112    movq %rsi, 16(%rsp)
113    .seh_savereg %rsi, 16
114    movups %xmm8, (%rsp)
115    .seh_savexmm %xmm8, 0
116    pushq %rbx
117    .seh_pushreg 3
118    mov %rsp, %rbx
119    .seh_setframe 3, 0
120    .seh_endprologue
121    .seh_handler __C_specific_handler, @except
122    .seh_handlerdata
123    .long 0
124    .text
125    .seh_startchained
126    .seh_endprologue
127    .seh_endchained
128    lea (%rbx), %rsp
129    pop %rbx
130    addq $24, %rsp
131    ret
132    .seh_endproc
133
134// Test emission of small functions.
135    .globl smallFunc
136    .def smallFunc; .scl 2; .type 32; .endef
137    .seh_proc smallFunc
138smallFunc:
139    ret
140    .seh_endproc
141