xref: /llvm-project/llvm/test/CodeGen/X86/fpenv.ll (revision a21abc782a8e1cb718a10c471a3b634f3102fc1c)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=-sse -verify-machineinstrs < %s | FileCheck %s -check-prefix=X86-NOSSE
3; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse -verify-machineinstrs < %s | FileCheck %s -check-prefix=X86-SSE
4; RUN: llc -mtriple=x86_64-unknown-linux-gnu -verify-machineinstrs < %s | FileCheck %s -check-prefix=X64
5
6declare void @llvm.set.rounding(i32 %x)
7declare i256 @llvm.get.fpenv.i256()
8declare void @llvm.set.fpenv.i256(i256 %fpenv)
9declare void @llvm.reset.fpenv()
10declare i32 @llvm.get.fpmode.i32()
11declare void @llvm.set.fpmode.i32(i32 %fpmode)
12declare void @llvm.reset.fpmode()
13
14define void @func_01() nounwind {
15; X86-NOSSE-LABEL: func_01:
16; X86-NOSSE:       # %bb.0:
17; X86-NOSSE-NEXT:    pushl %eax
18; X86-NOSSE-NEXT:    fnstcw (%esp)
19; X86-NOSSE-NEXT:    orb $12, {{[0-9]+}}(%esp)
20; X86-NOSSE-NEXT:    fldcw (%esp)
21; X86-NOSSE-NEXT:    popl %eax
22; X86-NOSSE-NEXT:    retl
23;
24; X86-SSE-LABEL: func_01:
25; X86-SSE:       # %bb.0:
26; X86-SSE-NEXT:    pushl %eax
27; X86-SSE-NEXT:    fnstcw (%esp)
28; X86-SSE-NEXT:    orb $12, {{[0-9]+}}(%esp)
29; X86-SSE-NEXT:    fldcw (%esp)
30; X86-SSE-NEXT:    stmxcsr (%esp)
31; X86-SSE-NEXT:    orb $96, {{[0-9]+}}(%esp)
32; X86-SSE-NEXT:    ldmxcsr (%esp)
33; X86-SSE-NEXT:    popl %eax
34; X86-SSE-NEXT:    retl
35;
36; X64-LABEL: func_01:
37; X64:       # %bb.0:
38; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
39; X64-NEXT:    orb $12, -{{[0-9]+}}(%rsp)
40; X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
41; X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
42; X64-NEXT:    orb $96, -{{[0-9]+}}(%rsp)
43; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
44; X64-NEXT:    retq
45  call void @llvm.set.rounding(i32 0)  ; TowardZero (CW[11-10] = 11)
46  ret void
47}
48
49define void @func_02() nounwind {
50; X86-NOSSE-LABEL: func_02:
51; X86-NOSSE:       # %bb.0:
52; X86-NOSSE-NEXT:    pushl %eax
53; X86-NOSSE-NEXT:    fnstcw (%esp)
54; X86-NOSSE-NEXT:    andb $-13, {{[0-9]+}}(%esp)
55; X86-NOSSE-NEXT:    fldcw (%esp)
56; X86-NOSSE-NEXT:    popl %eax
57; X86-NOSSE-NEXT:    retl
58;
59; X86-SSE-LABEL: func_02:
60; X86-SSE:       # %bb.0:
61; X86-SSE-NEXT:    pushl %eax
62; X86-SSE-NEXT:    fnstcw (%esp)
63; X86-SSE-NEXT:    andb $-13, {{[0-9]+}}(%esp)
64; X86-SSE-NEXT:    fldcw (%esp)
65; X86-SSE-NEXT:    stmxcsr (%esp)
66; X86-SSE-NEXT:    andb $-97, {{[0-9]+}}(%esp)
67; X86-SSE-NEXT:    ldmxcsr (%esp)
68; X86-SSE-NEXT:    popl %eax
69; X86-SSE-NEXT:    retl
70;
71; X64-LABEL: func_02:
72; X64:       # %bb.0:
73; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
74; X64-NEXT:    andb $-13, -{{[0-9]+}}(%rsp)
75; X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
76; X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
77; X64-NEXT:    andb $-97, -{{[0-9]+}}(%rsp)
78; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
79; X64-NEXT:    retq
80  call void @llvm.set.rounding(i32 1)  ; ToNearestTiesToEven (CW[11-10] = 00)
81  ret void
82}
83
84define void @func_03() nounwind {
85; X86-NOSSE-LABEL: func_03:
86; X86-NOSSE:       # %bb.0:
87; X86-NOSSE-NEXT:    pushl %eax
88; X86-NOSSE-NEXT:    fnstcw (%esp)
89; X86-NOSSE-NEXT:    movl $-3073, %eax # imm = 0xF3FF
90; X86-NOSSE-NEXT:    andl (%esp), %eax
91; X86-NOSSE-NEXT:    orl $2048, %eax # imm = 0x800
92; X86-NOSSE-NEXT:    movw %ax, (%esp)
93; X86-NOSSE-NEXT:    fldcw (%esp)
94; X86-NOSSE-NEXT:    popl %eax
95; X86-NOSSE-NEXT:    retl
96;
97; X86-SSE-LABEL: func_03:
98; X86-SSE:       # %bb.0:
99; X86-SSE-NEXT:    pushl %eax
100; X86-SSE-NEXT:    fnstcw (%esp)
101; X86-SSE-NEXT:    movl $-3073, %eax # imm = 0xF3FF
102; X86-SSE-NEXT:    andl (%esp), %eax
103; X86-SSE-NEXT:    orl $2048, %eax # imm = 0x800
104; X86-SSE-NEXT:    movw %ax, (%esp)
105; X86-SSE-NEXT:    fldcw (%esp)
106; X86-SSE-NEXT:    stmxcsr (%esp)
107; X86-SSE-NEXT:    movl $-24577, %eax # imm = 0x9FFF
108; X86-SSE-NEXT:    andl (%esp), %eax
109; X86-SSE-NEXT:    orl $16384, %eax # imm = 0x4000
110; X86-SSE-NEXT:    movl %eax, (%esp)
111; X86-SSE-NEXT:    ldmxcsr (%esp)
112; X86-SSE-NEXT:    popl %eax
113; X86-SSE-NEXT:    retl
114;
115; X64-LABEL: func_03:
116; X64:       # %bb.0:
117; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
118; X64-NEXT:    movl $-3073, %eax # imm = 0xF3FF
119; X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
120; X64-NEXT:    orl $2048, %eax # imm = 0x800
121; X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
122; X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
123; X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
124; X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
125; X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
126; X64-NEXT:    orl $16384, %eax # imm = 0x4000
127; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
128; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
129; X64-NEXT:    retq
130  call void @llvm.set.rounding(i32 2)  ; Upward (CW[11-10] = 10)
131  ret void
132}
133
134define void @func_04() nounwind {
135; X86-NOSSE-LABEL: func_04:
136; X86-NOSSE:       # %bb.0:
137; X86-NOSSE-NEXT:    pushl %eax
138; X86-NOSSE-NEXT:    fnstcw (%esp)
139; X86-NOSSE-NEXT:    movl $-3073, %eax # imm = 0xF3FF
140; X86-NOSSE-NEXT:    andl (%esp), %eax
141; X86-NOSSE-NEXT:    orl $1024, %eax # imm = 0x400
142; X86-NOSSE-NEXT:    movw %ax, (%esp)
143; X86-NOSSE-NEXT:    fldcw (%esp)
144; X86-NOSSE-NEXT:    popl %eax
145; X86-NOSSE-NEXT:    retl
146;
147; X86-SSE-LABEL: func_04:
148; X86-SSE:       # %bb.0:
149; X86-SSE-NEXT:    pushl %eax
150; X86-SSE-NEXT:    fnstcw (%esp)
151; X86-SSE-NEXT:    movl $-3073, %eax # imm = 0xF3FF
152; X86-SSE-NEXT:    andl (%esp), %eax
153; X86-SSE-NEXT:    orl $1024, %eax # imm = 0x400
154; X86-SSE-NEXT:    movw %ax, (%esp)
155; X86-SSE-NEXT:    fldcw (%esp)
156; X86-SSE-NEXT:    stmxcsr (%esp)
157; X86-SSE-NEXT:    movl $-24577, %eax # imm = 0x9FFF
158; X86-SSE-NEXT:    andl (%esp), %eax
159; X86-SSE-NEXT:    orl $8192, %eax # imm = 0x2000
160; X86-SSE-NEXT:    movl %eax, (%esp)
161; X86-SSE-NEXT:    ldmxcsr (%esp)
162; X86-SSE-NEXT:    popl %eax
163; X86-SSE-NEXT:    retl
164;
165; X64-LABEL: func_04:
166; X64:       # %bb.0:
167; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
168; X64-NEXT:    movl $-3073, %eax # imm = 0xF3FF
169; X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
170; X64-NEXT:    orl $1024, %eax # imm = 0x400
171; X64-NEXT:    movw %ax, -{{[0-9]+}}(%rsp)
172; X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
173; X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
174; X64-NEXT:    movl $-24577, %eax # imm = 0x9FFF
175; X64-NEXT:    andl -{{[0-9]+}}(%rsp), %eax
176; X64-NEXT:    orl $8192, %eax # imm = 0x2000
177; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
178; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
179; X64-NEXT:    retq
180  call void @llvm.set.rounding(i32 3)  ; Downward (CW[11-10] = 01)
181  ret void
182}
183
184define void @func_05(i32 %x) nounwind {
185; X86-NOSSE-LABEL: func_05:
186; X86-NOSSE:       # %bb.0:
187; X86-NOSSE-NEXT:    pushl %eax
188; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
189; X86-NOSSE-NEXT:    leal 4(%eax,%eax), %ecx
190; X86-NOSSE-NEXT:    movl $201, %eax
191; X86-NOSSE-NEXT:    # kill: def $cl killed $cl killed $ecx
192; X86-NOSSE-NEXT:    shll %cl, %eax
193; X86-NOSSE-NEXT:    andl $3072, %eax # imm = 0xC00
194; X86-NOSSE-NEXT:    fnstcw (%esp)
195; X86-NOSSE-NEXT:    movl $-3073, %ecx # imm = 0xF3FF
196; X86-NOSSE-NEXT:    andl (%esp), %ecx
197; X86-NOSSE-NEXT:    orl %eax, %ecx
198; X86-NOSSE-NEXT:    movw %cx, (%esp)
199; X86-NOSSE-NEXT:    fldcw (%esp)
200; X86-NOSSE-NEXT:    popl %eax
201; X86-NOSSE-NEXT:    retl
202;
203; X86-SSE-LABEL: func_05:
204; X86-SSE:       # %bb.0:
205; X86-SSE-NEXT:    pushl %eax
206; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
207; X86-SSE-NEXT:    leal 4(%eax,%eax), %ecx
208; X86-SSE-NEXT:    movl $201, %eax
209; X86-SSE-NEXT:    # kill: def $cl killed $cl killed $ecx
210; X86-SSE-NEXT:    shll %cl, %eax
211; X86-SSE-NEXT:    andl $3072, %eax # imm = 0xC00
212; X86-SSE-NEXT:    fnstcw (%esp)
213; X86-SSE-NEXT:    movl $-3073, %ecx # imm = 0xF3FF
214; X86-SSE-NEXT:    andl (%esp), %ecx
215; X86-SSE-NEXT:    orl %eax, %ecx
216; X86-SSE-NEXT:    movw %cx, (%esp)
217; X86-SSE-NEXT:    fldcw (%esp)
218; X86-SSE-NEXT:    stmxcsr (%esp)
219; X86-SSE-NEXT:    movl $-24577, %ecx # imm = 0x9FFF
220; X86-SSE-NEXT:    andl (%esp), %ecx
221; X86-SSE-NEXT:    leal (%ecx,%eax,8), %eax
222; X86-SSE-NEXT:    movl %eax, (%esp)
223; X86-SSE-NEXT:    ldmxcsr (%esp)
224; X86-SSE-NEXT:    popl %eax
225; X86-SSE-NEXT:    retl
226;
227; X64-LABEL: func_05:
228; X64:       # %bb.0:
229; X64-NEXT:    # kill: def $edi killed $edi def $rdi
230; X64-NEXT:    leal 4(%rdi,%rdi), %ecx
231; X64-NEXT:    movl $201, %eax
232; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
233; X64-NEXT:    shll %cl, %eax
234; X64-NEXT:    andl $3072, %eax # imm = 0xC00
235; X64-NEXT:    fnstcw -{{[0-9]+}}(%rsp)
236; X64-NEXT:    movl $-3073, %ecx # imm = 0xF3FF
237; X64-NEXT:    andl -{{[0-9]+}}(%rsp), %ecx
238; X64-NEXT:    orl %eax, %ecx
239; X64-NEXT:    movw %cx, -{{[0-9]+}}(%rsp)
240; X64-NEXT:    fldcw -{{[0-9]+}}(%rsp)
241; X64-NEXT:    stmxcsr -{{[0-9]+}}(%rsp)
242; X64-NEXT:    movl $-24577, %ecx # imm = 0x9FFF
243; X64-NEXT:    andl -{{[0-9]+}}(%rsp), %ecx
244; X64-NEXT:    leal (%rcx,%rax,8), %eax
245; X64-NEXT:    movl %eax, -{{[0-9]+}}(%rsp)
246; X64-NEXT:    ldmxcsr -{{[0-9]+}}(%rsp)
247; X64-NEXT:    retq
248  call void @llvm.set.rounding(i32 %x)  ; Downward
249  ret void
250}
251
252define void @get_fpenv_01(ptr %ptr) #0 {
253; X86-NOSSE-LABEL: get_fpenv_01:
254; X86-NOSSE:       # %bb.0: # %entry
255; X86-NOSSE-NEXT:    subl $60, %esp
256; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
257; X86-NOSSE-NEXT:    movl %eax, (%esp)
258; X86-NOSSE-NEXT:    calll fegetenv
259; X86-NOSSE-NEXT:    addl $60, %esp
260; X86-NOSSE-NEXT:    retl
261;
262; X86-SSE-LABEL: get_fpenv_01:
263; X86-SSE:       # %bb.0: # %entry
264; X86-SSE-NEXT:    subl $60, %esp
265; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
266; X86-SSE-NEXT:    movl %eax, (%esp)
267; X86-SSE-NEXT:    calll fegetenv
268; X86-SSE-NEXT:    addl $60, %esp
269; X86-SSE-NEXT:    retl
270;
271; X64-LABEL: get_fpenv_01:
272; X64:       # %bb.0: # %entry
273; X64-NEXT:    subq $40, %rsp
274; X64-NEXT:    callq fegetenv@PLT
275; X64-NEXT:    addq $40, %rsp
276; X64-NEXT:    retq
277entry:
278  %env = call i256 @llvm.get.fpenv.i256()
279  store i256 %env, ptr %ptr
280  ret void
281}
282
283define void @get_fpenv_01_native(ptr %ptr) nounwind {
284; X86-NOSSE-LABEL: get_fpenv_01_native:
285; X86-NOSSE:       # %bb.0: # %entry
286; X86-NOSSE-NEXT:    subl $44, %esp
287; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
288; X86-NOSSE-NEXT:    fnstenv (%eax)
289; X86-NOSSE-NEXT:    fldenv (%eax)
290; X86-NOSSE-NEXT:    addl $44, %esp
291; X86-NOSSE-NEXT:    retl
292;
293; X86-SSE-LABEL: get_fpenv_01_native:
294; X86-SSE:       # %bb.0: # %entry
295; X86-SSE-NEXT:    subl $44, %esp
296; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
297; X86-SSE-NEXT:    fnstenv (%eax)
298; X86-SSE-NEXT:    fldenv (%eax)
299; X86-SSE-NEXT:    stmxcsr 28(%eax)
300; X86-SSE-NEXT:    addl $44, %esp
301; X86-SSE-NEXT:    retl
302;
303; X64-LABEL: get_fpenv_01_native:
304; X64:       # %bb.0: # %entry
305; X64-NEXT:    fnstenv (%rdi)
306; X64-NEXT:    fldenv (%rdi)
307; X64-NEXT:    stmxcsr 28(%rdi)
308; X64-NEXT:    retq
309entry:
310  %env = call i256 @llvm.get.fpenv.i256()
311  store i256 %env, ptr %ptr
312  ret void
313}
314
315define void @set_fpenv_01(ptr %ptr) #0 {
316; X86-NOSSE-LABEL: set_fpenv_01:
317; X86-NOSSE:       # %bb.0: # %entry
318; X86-NOSSE-NEXT:    subl $60, %esp
319; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
320; X86-NOSSE-NEXT:    movl %eax, (%esp)
321; X86-NOSSE-NEXT:    calll fesetenv
322; X86-NOSSE-NEXT:    addl $60, %esp
323; X86-NOSSE-NEXT:    retl
324;
325; X86-SSE-LABEL: set_fpenv_01:
326; X86-SSE:       # %bb.0: # %entry
327; X86-SSE-NEXT:    subl $60, %esp
328; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
329; X86-SSE-NEXT:    movl %eax, (%esp)
330; X86-SSE-NEXT:    calll fesetenv
331; X86-SSE-NEXT:    addl $60, %esp
332; X86-SSE-NEXT:    retl
333;
334; X64-LABEL: set_fpenv_01:
335; X64:       # %bb.0: # %entry
336; X64-NEXT:    subq $40, %rsp
337; X64-NEXT:    callq fesetenv@PLT
338; X64-NEXT:    addq $40, %rsp
339; X64-NEXT:    retq
340entry:
341  %env = load i256, ptr %ptr
342  call void @llvm.set.fpenv.i256(i256 %env)
343  ret void
344}
345
346define void @set_fpenv_01_native(ptr %ptr) nounwind {
347; X86-NOSSE-LABEL: set_fpenv_01_native:
348; X86-NOSSE:       # %bb.0: # %entry
349; X86-NOSSE-NEXT:    subl $44, %esp
350; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
351; X86-NOSSE-NEXT:    fldenv (%eax)
352; X86-NOSSE-NEXT:    addl $44, %esp
353; X86-NOSSE-NEXT:    retl
354;
355; X86-SSE-LABEL: set_fpenv_01_native:
356; X86-SSE:       # %bb.0: # %entry
357; X86-SSE-NEXT:    subl $44, %esp
358; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
359; X86-SSE-NEXT:    fldenv (%eax)
360; X86-SSE-NEXT:    ldmxcsr 28(%eax)
361; X86-SSE-NEXT:    addl $44, %esp
362; X86-SSE-NEXT:    retl
363;
364; X64-LABEL: set_fpenv_01_native:
365; X64:       # %bb.0: # %entry
366; X64-NEXT:    fldenv (%rdi)
367; X64-NEXT:    ldmxcsr 28(%rdi)
368; X64-NEXT:    retq
369entry:
370  %env = load i256, ptr %ptr
371  call void @llvm.set.fpenv.i256(i256 %env)
372  ret void
373}
374
375define void @reset_fpenv_01() #0 {
376; X86-NOSSE-LABEL: reset_fpenv_01:
377; X86-NOSSE:       # %bb.0: # %entry
378; X86-NOSSE-NEXT:    subl $12, %esp
379; X86-NOSSE-NEXT:    movl $-1, (%esp)
380; X86-NOSSE-NEXT:    calll fesetenv
381; X86-NOSSE-NEXT:    addl $12, %esp
382; X86-NOSSE-NEXT:    retl
383;
384; X86-SSE-LABEL: reset_fpenv_01:
385; X86-SSE:       # %bb.0: # %entry
386; X86-SSE-NEXT:    subl $12, %esp
387; X86-SSE-NEXT:    movl $-1, (%esp)
388; X86-SSE-NEXT:    calll fesetenv
389; X86-SSE-NEXT:    addl $12, %esp
390; X86-SSE-NEXT:    retl
391;
392; X64-LABEL: reset_fpenv_01:
393; X64:       # %bb.0: # %entry
394; X64-NEXT:    pushq %rax
395; X64-NEXT:    movq $-1, %rdi
396; X64-NEXT:    callq fesetenv@PLT
397; X64-NEXT:    popq %rax
398; X64-NEXT:    retq
399entry:
400  call void @llvm.reset.fpenv()
401  ret void
402}
403
404define void @reset_fpenv_01_native() nounwind {
405; X86-NOSSE-LABEL: reset_fpenv_01_native:
406; X86-NOSSE:       # %bb.0: # %entry
407; X86-NOSSE-NEXT:    fldenv {{\.?LCPI[0-9]+_[0-9]+}}
408; X86-NOSSE-NEXT:    retl
409;
410; X86-SSE-LABEL: reset_fpenv_01_native:
411; X86-SSE:       # %bb.0: # %entry
412; X86-SSE-NEXT:    fldenv {{\.?LCPI[0-9]+_[0-9]+}}
413; X86-SSE-NEXT:    ldmxcsr {{\.?LCPI[0-9]+_[0-9]+}}+28
414; X86-SSE-NEXT:    retl
415;
416; X64-LABEL: reset_fpenv_01_native:
417; X64:       # %bb.0: # %entry
418; X64-NEXT:    fldenv {{\.?LCPI[0-9]+_[0-9]+}}(%rip)
419; X64-NEXT:    ldmxcsr {{\.?LCPI[0-9]+_[0-9]+}}+28(%rip)
420; X64-NEXT:    retq
421entry:
422  call void @llvm.reset.fpenv()
423  ret void
424}
425
426define i32 @func_get_fpmode() #0 {
427; X86-NOSSE-LABEL: func_get_fpmode:
428; X86-NOSSE:       # %bb.0: # %entry
429; X86-NOSSE-NEXT:    subl $12, %esp
430; X86-NOSSE-NEXT:    leal {{[0-9]+}}(%esp), %eax
431; X86-NOSSE-NEXT:    movl %eax, (%esp)
432; X86-NOSSE-NEXT:    calll fegetmode
433; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
434; X86-NOSSE-NEXT:    addl $12, %esp
435; X86-NOSSE-NEXT:    retl
436;
437; X86-SSE-LABEL: func_get_fpmode:
438; X86-SSE:       # %bb.0: # %entry
439; X86-SSE-NEXT:    subl $12, %esp
440; X86-SSE-NEXT:    leal {{[0-9]+}}(%esp), %eax
441; X86-SSE-NEXT:    movl %eax, (%esp)
442; X86-SSE-NEXT:    calll fegetmode
443; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
444; X86-SSE-NEXT:    addl $12, %esp
445; X86-SSE-NEXT:    retl
446;
447; X64-LABEL: func_get_fpmode:
448; X64:       # %bb.0: # %entry
449; X64-NEXT:    pushq %rax
450; X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
451; X64-NEXT:    callq fegetmode@PLT
452; X64-NEXT:    movl {{[0-9]+}}(%rsp), %eax
453; X64-NEXT:    popq %rcx
454; X64-NEXT:    retq
455entry:
456  %fpmode = call i32 @llvm.get.fpmode.i32()
457  ret i32 %fpmode
458}
459
460define void @func_set_fpmode(i32 %fpmode) #0 {
461; X86-NOSSE-LABEL: func_set_fpmode:
462; X86-NOSSE:       # %bb.0: # %entry
463; X86-NOSSE-NEXT:    subl $12, %esp
464; X86-NOSSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
465; X86-NOSSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
466; X86-NOSSE-NEXT:    leal {{[0-9]+}}(%esp), %eax
467; X86-NOSSE-NEXT:    movl %eax, (%esp)
468; X86-NOSSE-NEXT:    calll fesetmode
469; X86-NOSSE-NEXT:    addl $12, %esp
470; X86-NOSSE-NEXT:    retl
471;
472; X86-SSE-LABEL: func_set_fpmode:
473; X86-SSE:       # %bb.0: # %entry
474; X86-SSE-NEXT:    subl $12, %esp
475; X86-SSE-NEXT:    movl {{[0-9]+}}(%esp), %eax
476; X86-SSE-NEXT:    movl %eax, {{[0-9]+}}(%esp)
477; X86-SSE-NEXT:    leal {{[0-9]+}}(%esp), %eax
478; X86-SSE-NEXT:    movl %eax, (%esp)
479; X86-SSE-NEXT:    calll fesetmode
480; X86-SSE-NEXT:    addl $12, %esp
481; X86-SSE-NEXT:    retl
482;
483; X64-LABEL: func_set_fpmode:
484; X64:       # %bb.0: # %entry
485; X64-NEXT:    pushq %rax
486; X64-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
487; X64-NEXT:    leaq {{[0-9]+}}(%rsp), %rdi
488; X64-NEXT:    callq fesetmode@PLT
489; X64-NEXT:    popq %rax
490; X64-NEXT:    retq
491entry:
492  call void @llvm.set.fpmode.i32(i32 %fpmode)
493  ret void
494}
495
496
497define void @func_reset() #0 {
498; X86-NOSSE-LABEL: func_reset:
499; X86-NOSSE:       # %bb.0: # %entry
500; X86-NOSSE-NEXT:    subl $12, %esp
501; X86-NOSSE-NEXT:    movl $-1, (%esp)
502; X86-NOSSE-NEXT:    calll fesetmode
503; X86-NOSSE-NEXT:    addl $12, %esp
504; X86-NOSSE-NEXT:    retl
505;
506; X86-SSE-LABEL: func_reset:
507; X86-SSE:       # %bb.0: # %entry
508; X86-SSE-NEXT:    subl $12, %esp
509; X86-SSE-NEXT:    movl $-1, (%esp)
510; X86-SSE-NEXT:    calll fesetmode
511; X86-SSE-NEXT:    addl $12, %esp
512; X86-SSE-NEXT:    retl
513;
514; X64-LABEL: func_reset:
515; X64:       # %bb.0: # %entry
516; X64-NEXT:    pushq %rax
517; X64-NEXT:    movq $-1, %rdi
518; X64-NEXT:    callq fesetmode@PLT
519; X64-NEXT:    popq %rax
520; X64-NEXT:    retq
521entry:
522  call void @llvm.reset.fpmode()
523  ret void
524}
525
526attributes #0 = { nounwind "use-soft-float"="true" }
527