1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3; RUN:   | FileCheck -check-prefix=RV32IFD %s
4
5define double @fadd_d(double %a, double %b) nounwind {
6; RV32IFD-LABEL: fadd_d:
7; RV32IFD:       # %bb.0:
8; RV32IFD-NEXT:    addi sp, sp, -16
9; RV32IFD-NEXT:    sw a2, 8(sp)
10; RV32IFD-NEXT:    sw a3, 12(sp)
11; RV32IFD-NEXT:    fld ft0, 8(sp)
12; RV32IFD-NEXT:    sw a0, 8(sp)
13; RV32IFD-NEXT:    sw a1, 12(sp)
14; RV32IFD-NEXT:    fld ft1, 8(sp)
15; RV32IFD-NEXT:    fadd.d ft0, ft1, ft0
16; RV32IFD-NEXT:    fsd ft0, 8(sp)
17; RV32IFD-NEXT:    lw a0, 8(sp)
18; RV32IFD-NEXT:    lw a1, 12(sp)
19; RV32IFD-NEXT:    addi sp, sp, 16
20; RV32IFD-NEXT:    ret
21  %1 = fadd double %a, %b
22  ret double %1
23}
24
25define double @fsub_d(double %a, double %b) nounwind {
26; RV32IFD-LABEL: fsub_d:
27; RV32IFD:       # %bb.0:
28; RV32IFD-NEXT:    addi sp, sp, -16
29; RV32IFD-NEXT:    sw a2, 8(sp)
30; RV32IFD-NEXT:    sw a3, 12(sp)
31; RV32IFD-NEXT:    fld ft0, 8(sp)
32; RV32IFD-NEXT:    sw a0, 8(sp)
33; RV32IFD-NEXT:    sw a1, 12(sp)
34; RV32IFD-NEXT:    fld ft1, 8(sp)
35; RV32IFD-NEXT:    fsub.d ft0, ft1, ft0
36; RV32IFD-NEXT:    fsd ft0, 8(sp)
37; RV32IFD-NEXT:    lw a0, 8(sp)
38; RV32IFD-NEXT:    lw a1, 12(sp)
39; RV32IFD-NEXT:    addi sp, sp, 16
40; RV32IFD-NEXT:    ret
41  %1 = fsub double %a, %b
42  ret double %1
43}
44
45define double @fmul_d(double %a, double %b) nounwind {
46; RV32IFD-LABEL: fmul_d:
47; RV32IFD:       # %bb.0:
48; RV32IFD-NEXT:    addi sp, sp, -16
49; RV32IFD-NEXT:    sw a2, 8(sp)
50; RV32IFD-NEXT:    sw a3, 12(sp)
51; RV32IFD-NEXT:    fld ft0, 8(sp)
52; RV32IFD-NEXT:    sw a0, 8(sp)
53; RV32IFD-NEXT:    sw a1, 12(sp)
54; RV32IFD-NEXT:    fld ft1, 8(sp)
55; RV32IFD-NEXT:    fmul.d ft0, ft1, ft0
56; RV32IFD-NEXT:    fsd ft0, 8(sp)
57; RV32IFD-NEXT:    lw a0, 8(sp)
58; RV32IFD-NEXT:    lw a1, 12(sp)
59; RV32IFD-NEXT:    addi sp, sp, 16
60; RV32IFD-NEXT:    ret
61  %1 = fmul double %a, %b
62  ret double %1
63}
64
65define double @fdiv_d(double %a, double %b) nounwind {
66; RV32IFD-LABEL: fdiv_d:
67; RV32IFD:       # %bb.0:
68; RV32IFD-NEXT:    addi sp, sp, -16
69; RV32IFD-NEXT:    sw a2, 8(sp)
70; RV32IFD-NEXT:    sw a3, 12(sp)
71; RV32IFD-NEXT:    fld ft0, 8(sp)
72; RV32IFD-NEXT:    sw a0, 8(sp)
73; RV32IFD-NEXT:    sw a1, 12(sp)
74; RV32IFD-NEXT:    fld ft1, 8(sp)
75; RV32IFD-NEXT:    fdiv.d ft0, ft1, ft0
76; RV32IFD-NEXT:    fsd ft0, 8(sp)
77; RV32IFD-NEXT:    lw a0, 8(sp)
78; RV32IFD-NEXT:    lw a1, 12(sp)
79; RV32IFD-NEXT:    addi sp, sp, 16
80; RV32IFD-NEXT:    ret
81  %1 = fdiv double %a, %b
82  ret double %1
83}
84
85declare double @llvm.sqrt.f32(double)
86
87define double @fsqrt_d(double %a) nounwind {
88; RV32IFD-LABEL: fsqrt_d:
89; RV32IFD:       # %bb.0:
90; RV32IFD-NEXT:    addi sp, sp, -16
91; RV32IFD-NEXT:    sw a0, 8(sp)
92; RV32IFD-NEXT:    sw a1, 12(sp)
93; RV32IFD-NEXT:    fld ft0, 8(sp)
94; RV32IFD-NEXT:    fsqrt.d ft0, ft0
95; RV32IFD-NEXT:    fsd ft0, 8(sp)
96; RV32IFD-NEXT:    lw a0, 8(sp)
97; RV32IFD-NEXT:    lw a1, 12(sp)
98; RV32IFD-NEXT:    addi sp, sp, 16
99; RV32IFD-NEXT:    ret
100  %1 = call double @llvm.sqrt.f32(double %a)
101  ret double %1
102}
103
104declare double @llvm.copysign.f32(double, double)
105
106define double @fsgnj_d(double %a, double %b) nounwind {
107; RV32IFD-LABEL: fsgnj_d:
108; RV32IFD:       # %bb.0:
109; RV32IFD-NEXT:    addi sp, sp, -16
110; RV32IFD-NEXT:    sw a2, 8(sp)
111; RV32IFD-NEXT:    sw a3, 12(sp)
112; RV32IFD-NEXT:    fld ft0, 8(sp)
113; RV32IFD-NEXT:    sw a0, 8(sp)
114; RV32IFD-NEXT:    sw a1, 12(sp)
115; RV32IFD-NEXT:    fld ft1, 8(sp)
116; RV32IFD-NEXT:    fsgnj.d ft0, ft1, ft0
117; RV32IFD-NEXT:    fsd ft0, 8(sp)
118; RV32IFD-NEXT:    lw a0, 8(sp)
119; RV32IFD-NEXT:    lw a1, 12(sp)
120; RV32IFD-NEXT:    addi sp, sp, 16
121; RV32IFD-NEXT:    ret
122  %1 = call double @llvm.copysign.f32(double %a, double %b)
123  ret double %1
124}
125
126define double @fneg_d(double %a) nounwind {
127; RV32IFD-LABEL: fneg_d:
128; RV32IFD:       # %bb.0:
129; RV32IFD-NEXT:    addi sp, sp, -16
130; RV32IFD-NEXT:    sw a0, 8(sp)
131; RV32IFD-NEXT:    sw a1, 12(sp)
132; RV32IFD-NEXT:    fld ft0, 8(sp)
133; RV32IFD-NEXT:    fneg.d ft0, ft0
134; RV32IFD-NEXT:    fsd ft0, 8(sp)
135; RV32IFD-NEXT:    lw a0, 8(sp)
136; RV32IFD-NEXT:    lw a1, 12(sp)
137; RV32IFD-NEXT:    addi sp, sp, 16
138; RV32IFD-NEXT:    ret
139  %1 = fsub double -0.0, %a
140  ret double %1
141}
142
143define double @fsgnjn_d(double %a, double %b) nounwind {
144; RV32IFD-LABEL: fsgnjn_d:
145; RV32IFD:       # %bb.0:
146; RV32IFD-NEXT:    addi sp, sp, -16
147; RV32IFD-NEXT:    sw a2, 8(sp)
148; RV32IFD-NEXT:    sw a3, 12(sp)
149; RV32IFD-NEXT:    fld ft0, 8(sp)
150; RV32IFD-NEXT:    sw a0, 8(sp)
151; RV32IFD-NEXT:    sw a1, 12(sp)
152; RV32IFD-NEXT:    fld ft1, 8(sp)
153; RV32IFD-NEXT:    fsgnjn.d ft0, ft1, ft0
154; RV32IFD-NEXT:    fsd ft0, 8(sp)
155; RV32IFD-NEXT:    lw a0, 8(sp)
156; RV32IFD-NEXT:    lw a1, 12(sp)
157; RV32IFD-NEXT:    addi sp, sp, 16
158; RV32IFD-NEXT:    ret
159  %1 = fsub double -0.0, %b
160  %2 = call double @llvm.copysign.f32(double %a, double %1)
161  ret double %2
162}
163
164declare double @llvm.fabs.f32(double)
165
166define double @fabs_d(double %a) nounwind {
167; RV32IFD-LABEL: fabs_d:
168; RV32IFD:       # %bb.0:
169; RV32IFD-NEXT:    addi sp, sp, -16
170; RV32IFD-NEXT:    sw a0, 8(sp)
171; RV32IFD-NEXT:    sw a1, 12(sp)
172; RV32IFD-NEXT:    fld ft0, 8(sp)
173; RV32IFD-NEXT:    fabs.d ft0, ft0
174; RV32IFD-NEXT:    fsd ft0, 8(sp)
175; RV32IFD-NEXT:    lw a0, 8(sp)
176; RV32IFD-NEXT:    lw a1, 12(sp)
177; RV32IFD-NEXT:    addi sp, sp, 16
178; RV32IFD-NEXT:    ret
179  %1 = call double @llvm.fabs.f32(double %a)
180  ret double %1
181}
182
183declare double @llvm.minnum.f32(double, double)
184
185define double @fmin_d(double %a, double %b) nounwind {
186; RV32IFD-LABEL: fmin_d:
187; RV32IFD:       # %bb.0:
188; RV32IFD-NEXT:    addi sp, sp, -16
189; RV32IFD-NEXT:    sw a2, 8(sp)
190; RV32IFD-NEXT:    sw a3, 12(sp)
191; RV32IFD-NEXT:    fld ft0, 8(sp)
192; RV32IFD-NEXT:    sw a0, 8(sp)
193; RV32IFD-NEXT:    sw a1, 12(sp)
194; RV32IFD-NEXT:    fld ft1, 8(sp)
195; RV32IFD-NEXT:    fmin.d ft0, ft1, ft0
196; RV32IFD-NEXT:    fsd ft0, 8(sp)
197; RV32IFD-NEXT:    lw a0, 8(sp)
198; RV32IFD-NEXT:    lw a1, 12(sp)
199; RV32IFD-NEXT:    addi sp, sp, 16
200; RV32IFD-NEXT:    ret
201  %1 = call double @llvm.minnum.f32(double %a, double %b)
202  ret double %1
203}
204
205declare double @llvm.maxnum.f32(double, double)
206
207define double @fmax_d(double %a, double %b) nounwind {
208; RV32IFD-LABEL: fmax_d:
209; RV32IFD:       # %bb.0:
210; RV32IFD-NEXT:    addi sp, sp, -16
211; RV32IFD-NEXT:    sw a2, 8(sp)
212; RV32IFD-NEXT:    sw a3, 12(sp)
213; RV32IFD-NEXT:    fld ft0, 8(sp)
214; RV32IFD-NEXT:    sw a0, 8(sp)
215; RV32IFD-NEXT:    sw a1, 12(sp)
216; RV32IFD-NEXT:    fld ft1, 8(sp)
217; RV32IFD-NEXT:    fmax.d ft0, ft1, ft0
218; RV32IFD-NEXT:    fsd ft0, 8(sp)
219; RV32IFD-NEXT:    lw a0, 8(sp)
220; RV32IFD-NEXT:    lw a1, 12(sp)
221; RV32IFD-NEXT:    addi sp, sp, 16
222; RV32IFD-NEXT:    ret
223  %1 = call double @llvm.maxnum.f32(double %a, double %b)
224  ret double %1
225}
226
227define i32 @feq_d(double %a, double %b) nounwind {
228; RV32IFD-LABEL: feq_d:
229; RV32IFD:       # %bb.0:
230; RV32IFD-NEXT:    addi sp, sp, -16
231; RV32IFD-NEXT:    sw a2, 8(sp)
232; RV32IFD-NEXT:    sw a3, 12(sp)
233; RV32IFD-NEXT:    fld ft0, 8(sp)
234; RV32IFD-NEXT:    sw a0, 8(sp)
235; RV32IFD-NEXT:    sw a1, 12(sp)
236; RV32IFD-NEXT:    fld ft1, 8(sp)
237; RV32IFD-NEXT:    feq.d a0, ft1, ft0
238; RV32IFD-NEXT:    addi sp, sp, 16
239; RV32IFD-NEXT:    ret
240  %1 = fcmp oeq double %a, %b
241  %2 = zext i1 %1 to i32
242  ret i32 %2
243}
244
245define i32 @flt_d(double %a, double %b) nounwind {
246; RV32IFD-LABEL: flt_d:
247; RV32IFD:       # %bb.0:
248; RV32IFD-NEXT:    addi sp, sp, -16
249; RV32IFD-NEXT:    sw a2, 8(sp)
250; RV32IFD-NEXT:    sw a3, 12(sp)
251; RV32IFD-NEXT:    fld ft0, 8(sp)
252; RV32IFD-NEXT:    sw a0, 8(sp)
253; RV32IFD-NEXT:    sw a1, 12(sp)
254; RV32IFD-NEXT:    fld ft1, 8(sp)
255; RV32IFD-NEXT:    flt.d a0, ft1, ft0
256; RV32IFD-NEXT:    addi sp, sp, 16
257; RV32IFD-NEXT:    ret
258  %1 = fcmp olt double %a, %b
259  %2 = zext i1 %1 to i32
260  ret i32 %2
261}
262
263define i32 @fle_d(double %a, double %b) nounwind {
264; RV32IFD-LABEL: fle_d:
265; RV32IFD:       # %bb.0:
266; RV32IFD-NEXT:    addi sp, sp, -16
267; RV32IFD-NEXT:    sw a2, 8(sp)
268; RV32IFD-NEXT:    sw a3, 12(sp)
269; RV32IFD-NEXT:    fld ft0, 8(sp)
270; RV32IFD-NEXT:    sw a0, 8(sp)
271; RV32IFD-NEXT:    sw a1, 12(sp)
272; RV32IFD-NEXT:    fld ft1, 8(sp)
273; RV32IFD-NEXT:    fle.d a0, ft1, ft0
274; RV32IFD-NEXT:    addi sp, sp, 16
275; RV32IFD-NEXT:    ret
276  %1 = fcmp ole double %a, %b
277  %2 = zext i1 %1 to i32
278  ret i32 %2
279}
280