• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -relocation-model=pic -march=mipsel -mcpu=mips32r5 \
2; RUN:     -mattr=+fp64,+msa -verify-machineinstrs < %s | FileCheck %s \
3; RUN:     --check-prefixes=ALL,MIPS32,MIPSR5,MIPS32-O32,MIPS32R5-O32
4; RUN: llc -relocation-model=pic -march=mips64el -mcpu=mips64r5 \
5; RUN:     -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 < %s | FileCheck %s \
6; RUN:     --check-prefixes=ALL,MIPS64,MIPSR5,MIPS64-N32,MIPS64R5-N32
7; RUN: llc -relocation-model=pic -march=mips64el -mcpu=mips64r5 \
8; RUN:     -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 < %s | FileCheck %s \
9; RUN:     --check-prefixes=ALL,MIPS64,MIPSR5,MIPS64-N64,MIPS64R5-N64
10
11; RUN: llc -relocation-model=pic -march=mipsel -mcpu=mips32r6 \
12; RUN:     -mattr=+fp64,+msa -verify-machineinstrs < %s | FileCheck %s \
13; RUN:     --check-prefixes=ALL,MIPS32,MIPSR6,MIPSR6-O32
14; RUN: llc -relocation-model=pic -march=mips64el -mcpu=mips64r6 \
15; RUN:     -mattr=+fp64,+msa -verify-machineinstrs -target-abi n32 < %s | FileCheck %s \
16; RUN:     --check-prefixes=ALL,MIPS64,MIPSR6,MIPS64-N32,MIPSR6-N32
17; RUN: llc -relocation-model=pic -march=mips64el -mcpu=mips64r6 \
18; RUN:     -mattr=+fp64,+msa -verify-machineinstrs -target-abi n64 < %s | FileCheck %s \
19; RUN:     --check-prefixes=ALL,MIPS64,MIPSR6,MIPS64-N64,MIPSR6-N64
20
21
22; Check the use of frame indexes in the msa pseudo f16 instructions.
23
24@k = external global float
25
26declare float @k2(half *)
27
28define void @f3(i16 %b) {
29entry:
30; ALL-LABEL: f3:
31
32; ALL: sh $4, [[O0:[0-9]+]]($sp)
33; ALL-DAG: jalr $25
34; MIPS32-DAG: addiu $4, $sp, [[O0]]
35; MIPS64-N32: addiu $4, $sp, [[O0]]
36; MIPS64-N64: daddiu $4, $sp, [[O0]]
37; ALL: swc1 $f0
38
39  %0 = alloca half
40  %1 = bitcast i16 %b to half
41  store half %1, half * %0
42  %2 = call float @k2(half * %0)
43  store float %2, float * @k
44  ret void
45}
46
47define void  @f(i16 %b) {
48; ALL-LABEL: f:
49
50; ALL: sh $4, [[O0:[0-9]+]]($sp)
51; ALL: lh $[[R0:[0-9]+]], [[O0]]($sp)
52; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
53; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
54; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
55; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
56; ALL: swc1 $f[[F0]]
57
58  %1 = bitcast i16 %b to half
59  %2 = fpext half %1 to float
60  store float %2, float * @k
61  ret void
62}
63
64@g = external global i16, align 2
65@h = external global half, align 2
66
67; Check that fext f16 to double has a fexupr.w, fexupr.d sequence.
68; Check that ftrunc double to f16 has fexdo.w, fexdo.h sequence.
69; Check that MIPS64R5+ uses 64-bit floating point <-> 64-bit GPR transfers.
70
71; We don't need to check if pre-MIPSR5 expansions occur, the MSA ASE requires
72; MIPSR5. Additionally, fp64 mode / FR=1 is required to use MSA.
73
74define void @fadd_f64() {
75entry:
76; ALL-LABEL: fadd_f64:
77  %0 = load half, half * @h, align 2
78  %1 = fpext half %0 to double
79; ALL:    lh $[[R0:[0-9]+]]
80; ALL:    fill.h $w[[W0:[0-9]+]], $[[R0]]
81; ALL:    fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
82; ALL:    fexupr.d $w[[W2:[0-9]+]], $w[[W1]]
83; MIPS32: copy_s.w $[[R1:[0-9]+]], $w[[W2]][0]
84; MIPS32: mtc1 $[[R1]], $f[[F0:[0-9]+]]
85; MIPS32: copy_s.w $[[R2:[0-9]+]], $w[[W2]][1]
86; MIPS32: mthc1 $[[R2]], $f[[F0]]
87; MIPS64: copy_s.d $[[R2:[0-9]+]], $w[[W2]][0]
88; MIPS64: dmtc1 $[[R2]], $f[[F0:[0-9]+]]
89
90  %2 = load half, half * @h, align 2
91  %3 = fpext half %2 to double
92  %add = fadd double %1, %3
93
94; ALL: add.d $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
95
96  %4 = fptrunc double %add to half
97
98; MIPS32: mfc1 $[[R2:[0-9]+]], $f[[F1]]
99; MIPS32: fill.w $w[[W2:[0-9]+]], $[[R2]]
100; MIPS32: mfhc1 $[[R3:[0-9]+]], $f[[F1]]
101; MIPS32: insert.w $w[[W2]][1], $[[R3]]
102; MIPS32: insert.w $w[[W2]][3], $[[R3]]
103
104; MIPS64: dmfc1 $[[R2:[0-9]+]], $f[[F1]]
105; MIPS64: fill.d $w[[W2:[0-9]+]], $[[R2]]
106
107; ALL:    fexdo.w $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
108; ALL:    fexdo.h $w[[W4:[0-9]+]], $w[[W3]], $w[[W3]]
109; ALL:    copy_u.h $[[R3:[0-9]+]], $w[[W4]][0]
110; ALL:    sh $[[R3]]
111   store half %4, half * @h, align 2
112  ret void
113}
114
115define i32 @ffptoui() {
116entry:
117; ALL-LABEL: ffptoui:
118  %0 = load half, half * @h, align 2
119  %1 = fptoui half %0 to i32
120
121; MIPS32:       lwc1 $f[[FC:[0-9]+]], %lo($CPI{{[0-9]+}}_{{[0-9]+}})
122; MIPS64-N32:   lwc1 $f[[FC:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}})
123; MIPS64-N64:   lwc1 $f[[FC:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}})
124
125; ALL:          lh $[[R0:[0-9]+]]
126; ALL:          fill.h $w[[W0:[0-9]+]], $[[R0]]
127; ALL:          fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
128; ALL:          copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
129; ALL:          mtc1 $[[R1]], $f[[F0:[0-9]+]]
130; MIPSR6:       cmp.lt.s  $f[[F1:[0-9]+]], $f[[F0]], $f[[FC]]
131; ALL:          sub.s $f[[F2:[0-9]+]], $f[[F0]], $f[[FC]]
132; ALL:          mfc1 $[[R2:[0-9]]], $f[[F2]]
133; ALL:          fill.w $w[[W2:[0-9]+]], $[[R2]]
134; ALL:          fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
135; ALL:          fexupr.w $w[[W4:[0-9]+]], $w[[W3]]
136; ALL:          fexupr.d $w[[W5:[0-9]+]], $w[[W4]]
137
138; MIPS32:       copy_s.w $[[R3:[0-9]+]], $w[[W5]][0]
139; MIPS32:       mtc1 $[[R3]], $f[[F3:[0-9]+]]
140; MIPS32:       copy_s.w $[[R4:[0-9]+]], $w[[W5]][1]
141; MIPS32:       mthc1 $[[R3]], $f[[F3]]
142
143; MIPS64:       copy_s.d $[[R2:[0-9]+]], $w[[W2]][0]
144; MIPS64:       dmtc1 $[[R2]], $f[[F3:[0-9]+]]
145
146; ALL:          trunc.w.d $f[[F4:[0-9]+]], $f[[F3]]
147; ALL:          mfc1 $[[R4:[0-9]+]], $f[[F4]]
148; ALL:          fexupr.d $w[[W6:[0-9]+]], $w[[W1]]
149
150; MIPS32:       copy_s.w $[[R5:[0-9]+]], $w[[W6]][0]
151; MIPS32:       mtc1 $[[R5]], $f[[F5:[0-9]+]]
152; MIPS32:       copy_s.w $[[R6:[0-9]+]], $w[[W6]][1]
153; MIPS32:       mthc1 $[[R6]], $f[[F5]]
154
155; MIPS64:       copy_s.d $[[R2:[0-9]+]], $w[[W2]][0]
156; MIPS64:       dmtc1 $[[R2]], $f[[F5:[0-9]+]]
157
158; ALL:          trunc.w.d $f[[F6:[0-9]]], $f[[F5]]
159; ALL:          mfc1 $[[R7:[0-9]]], $f[[F6]]
160
161; MIPS32R5-O32: lw $[[R13:[0-9]+]], %got($CPI{{[0-9]+}}_{{[0-9]+}})
162; MIPS32R5-O32: addiu $[[R14:[0-9]+]], $[[R13]], %lo($CPI{{[0-9]+}}_{{[0-9]+}})
163
164; MIPS64R5-N32: lw $[[R13:[0-9]+]], %got_page(.LCPI{{[0-9]+}}_{{[0-9]+}})
165; MIPS64R5-N32: addiu $[[R14:[0-9]+]], $[[R13]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}})
166
167; MIPS64R5-N64: ld $[[R13:[0-9]+]], %got_page(.LCPI{{[0-9]+}}_{{[0-9]+}})
168; MIPS64R5-N64: daddiu $[[R14:[0-9]+]], $[[R13]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}})
169
170; ALL:          lui $[[R8:[0-9]+]], 32768
171; ALL:          xor $[[R9:[0-9]+]], $[[R4]], $[[R8]]
172
173; MIPSR5:       lh $[[R15:[0-9]+]], 0($[[R14]])
174; MIPSR5:       fill.h $w[[W7:[0-9]+]], $[[R15]]
175; MIPSR5:       fexupr.w $w[[W8:[0-9]+]], $w[[W7]]
176; MIPSR5:       copy_s.w $[[R16:[0-9]+]], $w[[W8]][0]
177; MIPSR5:       mtc1 $[[R16]], $f[[F7:[0-9]+]]
178; MIPSR5:       c.olt.s $f[[F0]], $f[[F7]]
179; MIPSR5:       movt $[[R9]], $[[R7]], $fcc0
180
181; MIPSR6:       mfc1 $[[R10:[0-9]+]], $f[[F1]]
182; MIPSR6:       seleqz $[[R11:[0-9]]], $[[R9]], $[[R10]]
183; MIPSR6:       selnez $[[R12:[0-9]]], $[[R7]], $[[R10]]
184; MIPSR6:       or $2, $[[R12]], $[[R11]]
185
186  ret i32 %1
187}
188
189define i32 @ffptosi() {
190entry:
191; ALL-LABEL: ffptosi:
192  %0 = load half, half * @h, align 2
193  %1 = fptosi half %0 to i32
194  ret i32 %1
195
196; ALL:    lh $[[R0:[0-9]+]]
197; ALL:    fill.h $w[[W0:[0-9]+]], $[[R0]]
198; ALL:    fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
199; ALL:    fexupr.d $w[[W2:[0-9]+]], $w[[W1]]
200
201; MIPS32: copy_s.w $[[R2:[0-9]+]], $w[[W2]][0]
202; MIPS32: mtc1 $[[R2]], $f[[F0:[0-9]+]]
203; MIPS32: copy_s.w $[[R3:[0-9]+]], $w[[W2]][1]
204; MIPS32: mthc1 $[[R3]], $f[[F0]]
205
206; MIPS64: copy_s.d $[[R2:[0-9]+]], $w[[W2]][0]
207; MIPS64: dmtc1 $[[R2]], $f[[F0:[0-9]+]]
208
209; ALL:    trunc.w.d $f[[F1:[0-9]+]], $f[[F0]]
210; ALL:    mfc1 $2, $f[[F1]]
211}
212
213define void @uitofp(i32 %a) {
214entry:
215; ALL-LABEL: uitofp:
216
217; MIPS32-O32: ldc1 $f[[F0:[0-9]+]], %lo($CPI{{[0-9]+}}_{{[0-9]+}})
218; MIPS32-O32: ldc1 $f[[F1:[0-9]+]], 0($sp)
219
220; MIPS64-N32: ldc1 $f[[F0:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}})
221; MIPS64-N32: ldc1 $f[[F1:[0-9]+]], 8($sp)
222
223; MIPS64-N64: ldc1 $f[[F0:[0-9]+]], %got_ofst(.LCPI{{[0-9]+}}_{{[0-9]+}})
224; MIPS64-N64: ldc1 $f[[F1:[0-9]+]], 8($sp)
225
226; MIPSR5:     sub.d $f[[F2:[0-9]+]], $f[[F1]], $f[[F0]]
227; MIPSR6-O32: sub.d $f[[F2:[0-9]+]], $f[[F0]], $f[[F1]]
228; MIPSR6-N32: sub.d $f[[F2:[0-9]+]], $f[[F1]], $f[[F0]]
229; MIPSR6-N64: sub.d $f[[F2:[0-9]+]], $f[[F1]], $f[[F0]]
230
231; MIPS32:     mfc1 $[[R0:[0-9]+]], $f[[F2]]
232; MIPS32:     fill.w $w[[W0:[0-9]+]], $[[R0]]
233; MIPS32:     mfhc1 $[[R1:[0-9]+]], $f[[F2]]
234; MIPS32:     insert.w $w[[W0]][1], $[[R1]]
235; MIPS32:     insert.w $w[[W0]][3], $[[R1]]
236
237; MIPS64-N64-DAG: ld $[[R3:[0-9]+]], %got_disp(h)
238; MIPS64-N32-DAG: lw $[[R3:[0-9]+]], %got_disp(h)
239; MIPS64-DAG:     dmfc1 $[[R1:[0-9]+]], $f[[F2]]
240; MIPS64-DAG:     fill.d $w[[W0:[0-9]+]], $[[R1]]
241
242; ALL-DAG:        fexdo.w $w[[W1:[0-9]+]], $w[[W0]], $w[[W0]]
243; ALL-DAG:        fexdo.h $w[[W2:[0-9]+]], $w[[W1]], $w[[W1]]
244
245; MIPS32-DAG:     lw $[[R3:[0-9]+]], %got(h)
246
247; ALL:        copy_u.h $[[R2:[0-9]+]], $w[[W2]]
248; ALL:        sh $[[R2]], 0($[[R3]])
249  %0 = uitofp i32 %a to half
250  store half %0, half * @h, align 2
251  ret void
252}
253
254
255; Check that f16 is expanded to f32 and relevant transfer ops occur.
256; We don't check f16 -> f64 expansion occurs, as we expand f16 to f32.
257
258define void @fadd() {
259entry:
260; ALL-LABEL: fadd:
261  %0 = load i16, i16* @g, align 2
262  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
263
264; ALL: lh $[[R0:[0-9]+]]
265; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
266; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
267; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
268; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
269
270  %2 = load i16, i16* @g, align 2
271  %3 = call float @llvm.convert.from.fp16.f32(i16 %2)
272  %add = fadd float %1, %3
273
274; ALL: add.s $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
275
276 %4 = call i16 @llvm.convert.to.fp16.f32(float %add)
277
278; ALL: mfc1 $[[R2:[0-9]+]], $f[[F1]]
279; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]]
280; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
281; ALL: copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
282; ALL: sh $[[R3]]
283   store i16 %4, i16* @g, align 2
284  ret void
285}
286
287; Function Attrs: nounwind readnone
288declare float @llvm.convert.from.fp16.f32(i16)
289
290; Function Attrs: nounwind readnone
291declare i16 @llvm.convert.to.fp16.f32(float)
292
293; Function Attrs: nounwind
294define void @fsub() {
295entry:
296; ALL-LABEL: fsub:
297  %0 = load i16, i16* @g, align 2
298  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
299
300; ALL: lh $[[R0:[0-9]+]]
301; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
302; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
303; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
304; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
305
306  %2 = load i16, i16* @g, align 2
307  %3 = call float @llvm.convert.from.fp16.f32(i16 %2)
308  %sub = fsub float %1, %3
309
310; ALL: sub.s $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
311
312  %4 = call i16 @llvm.convert.to.fp16.f32(float %sub)
313
314; ALL: mfc1 $[[R2:[0-9]+]], $f[[F1]]
315; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]]
316; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
317; ALL: copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
318
319  store i16 %4, i16* @g, align 2
320; ALL: sh $[[R3]]
321  ret void
322}
323
324define void @fmult() {
325entry:
326; ALL-LABEL: fmult:
327  %0 = load i16, i16* @g, align 2
328  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
329
330; ALL: lh $[[R0:[0-9]+]]
331; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
332; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
333; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
334; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
335
336  %2 = load i16, i16* @g, align 2
337  %3 = call float @llvm.convert.from.fp16.f32(i16 %2)
338  %mul = fmul float %1, %3
339
340; ALL: mul.s $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
341
342  %4 = call i16 @llvm.convert.to.fp16.f32(float %mul)
343
344; ALL: mfc1 $[[R2:[0-9]+]], $f[[F1]]
345; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]]
346; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
347; ALL: copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
348
349  store i16 %4, i16* @g, align 2
350
351; ALL: sh $[[R3]]
352  ret void
353}
354
355define void @fdiv() {
356entry:
357; ALL-LABEL: fdiv:
358
359  %0 = load i16, i16* @g, align 2
360  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
361
362; ALL: lh $[[R0:[0-9]+]]
363; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
364; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
365; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
366; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
367
368  %2 = load i16, i16* @g, align 2
369  %3 = call float @llvm.convert.from.fp16.f32(i16 %2)
370  %div = fdiv float %1, %3
371
372; ALL: div.s $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
373
374  %4 = call i16 @llvm.convert.to.fp16.f32(float %div)
375
376; ALL: mfc1 $[[R2:[0-9]+]], $f[[F1]]
377; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]]
378; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
379; ALL: copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
380  store i16 %4, i16* @g, align 2
381; ALL: sh $[[R3]]
382  ret void
383}
384
385define void @frem() {
386entry:
387; ALL-LABEL: frem:
388  %0 = load i16, i16* @g, align 2
389  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
390
391; ALL:        lh $[[R0:[0-9]+]]
392; ALL:        fill.h $w[[W0:[0-9]+]], $[[R0]]
393; ALL:        fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
394; ALL:        copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
395; ALL:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
396
397  %2 = load i16, i16* @g, align 2
398  %3 = call float @llvm.convert.from.fp16.f32(i16 %2)
399  %rem = frem float %1, %3
400
401; MIPS32:     lw $25, %call16(fmodf)($gp)
402; MIPS64-N32: lw $25, %call16(fmodf)($gp)
403; MIPS64-N64: ld $25, %call16(fmodf)($gp)
404; ALL:        jalr $25
405
406  %4 = call i16 @llvm.convert.to.fp16.f32(float %rem)
407
408; ALL:        mfc1 $[[R2:[0-9]+]], $f[[F1]]
409; ALL:        fill.w $w[[W2:[0-9]+]], $[[R2]]
410; ALL:        fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
411; ALL:        copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
412
413  store i16 %4, i16* @g, align 2
414; ALL:        sh $[[R3]]
415
416  ret void
417}
418
419@i1 = external global i16, align 1
420
421define void @fcmp() {
422entry:
423; ALL-LABEL: fcmp:
424  %0 = load i16, i16* @g, align 2
425  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
426; ALL:        lh $[[R0:[0-9]+]]
427; ALL:        fill.h $w[[W0:[0-9]+]], $[[R0]]
428; ALL:        fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
429; ALL:        copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
430; ALL:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
431
432  %2 = load i16, i16* @g, align 2
433  %3 = call float @llvm.convert.from.fp16.f32(i16 %2)
434  %fcmp = fcmp oeq float %1, %3
435
436; MIPSR5: addiu $[[R2:[0-9]+]], $zero, 1
437; MIPSR5: c.un.s $f[[F0]], $f[[F0]]
438; MIPSR5: movt $[[R2]], $zero, $fcc0
439; MIPSR6: cmp.un.s $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
440; MIPSR6: mfc1 $[[R3:[0-9]]], $f[[F1]]
441; MIPSR6: not $[[R4:[0-9]+]], $[[R3]]
442; MIPSR6: andi $[[R2:[0-9]+]], $[[R4]], 1
443
444  %4 = zext i1 %fcmp to i16
445  store i16 %4, i16* @i1, align 2
446; ALL:        sh $[[R2]]
447
448  ret void
449}
450
451declare float @llvm.powi.f32(float, i32)
452
453define void @fpowi() {
454entry:
455; ALL-LABEL: fpowi:
456  %0 = load i16, i16* @g, align 2
457  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
458
459; ALL: lh $[[R0:[0-9]+]]
460; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
461; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
462; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
463; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
464
465  %powi = call float @llvm.powi.f32(float %1, i32 2)
466
467; ALL: mul.s $f[[F1:[0-9]+]], $f[[F0]], $f[[F0]]
468
469  %2 = call i16 @llvm.convert.to.fp16.f32(float %powi)
470
471; ALL: mfc1 $[[R2:[0-9]+]], $f[[F1]]
472; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]]
473; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
474; ALL: copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
475
476  store i16 %2, i16* @g, align 2
477; ALL: sh $[[R3]]
478  ret void
479}
480
481define void @fpowi_var(i32 %var) {
482entry:
483; ALL-LABEL: fpowi_var:
484  %0 = load i16, i16* @g, align 2
485  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
486
487; ALL:            lh $[[R0:[0-9]+]]
488; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
489; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
490; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
491
492  %powi = call float @llvm.powi.f32(float %1, i32 %var)
493
494; ALL-DAG: mtc1 $[[R1]], $f[[F0:[0-9]+]]
495; MIPS32-DAG:     lw $25, %call16(__powisf2)($gp)
496; MIPS64-N32-DAG: lw $25, %call16(__powisf2)($gp)
497; MIPS64-N64-DAG: ld $25, %call16(__powisf2)($gp)
498; ALL-DAG:        jalr $25
499
500  %2 = call i16 @llvm.convert.to.fp16.f32(float %powi)
501
502; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
503; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
504; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
505; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
506
507  store i16 %2, i16* @g, align 2
508; ALL:            sh $[[R3]]
509  ret void
510}
511
512declare float @llvm.pow.f32(float %Val, float %power)
513
514define void @fpow(float %var) {
515entry:
516; ALL-LABEL: fpow:
517  %0 = load i16, i16* @g, align 2
518  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
519
520; ALL:            lh $[[R0:[0-9]+]]
521; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
522; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
523; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
524
525  %powi = call float @llvm.pow.f32(float %1, float %var)
526
527; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
528; MIPS32-DAG:     lw $25, %call16(powf)($gp)
529; MIPS64-N32-DAG: lw $25, %call16(powf)($gp)
530; MIPS64-N64-DAG: ld $25, %call16(powf)($gp)
531; ALL-DAG:        jalr $25
532
533  %2 = call i16 @llvm.convert.to.fp16.f32(float %powi)
534
535; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
536; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
537; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
538; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
539
540  store i16 %2, i16* @g, align 2
541; ALL:            sh $[[R3]]
542  ret void
543}
544
545declare float @llvm.log2.f32(float %Val)
546
547define void @flog2() {
548entry:
549; ALL-LABEL: flog2:
550  %0 = load i16, i16* @g, align 2
551  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
552
553; ALL:            lh $[[R0:[0-9]+]]
554; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
555; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
556; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
557; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
558; MIPS32-DAG:     lw $25, %call16(log2f)($gp)
559; MIPS64-N32-DAG: lw $25, %call16(log2f)($gp)
560; MIPS64-N64-DAG: ld $25, %call16(log2f)($gp)
561; ALL-DAG:        jalr $25
562
563  %log2 = call float @llvm.log2.f32(float %1)
564  %2 = call i16 @llvm.convert.to.fp16.f32(float %log2)
565
566; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
567; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
568; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
569; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
570
571  store i16 %2, i16* @g, align 2
572; ALL:            sh $[[R3]]
573
574  ret void
575}
576
577declare float @llvm.log10.f32(float %Val)
578
579define void @flog10() {
580entry:
581; ALL-LABEL: flog10:
582  %0 = load i16, i16* @g, align 2
583  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
584
585; ALL:            lh $[[R0:[0-9]+]]
586; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
587; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
588; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
589; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
590; MIPS32-DAG:     lw $25, %call16(log10f)($gp)
591; MIPS64-N32-DAG: lw $25, %call16(log10f)($gp)
592; MIPS64-N64-DAG: ld $25, %call16(log10f)($gp)
593; ALL-DAG:        jalr $25
594
595  %log10 = call float @llvm.log10.f32(float %1)
596  %2 = call i16 @llvm.convert.to.fp16.f32(float %log10)
597
598; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
599; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
600; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
601; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
602
603  store i16 %2, i16* @g, align 2
604; ALL:            sh $[[R3]]
605
606  ret void
607}
608
609declare float @llvm.sqrt.f32(float %Val)
610
611define void @fsqrt() {
612entry:
613; ALL-LABEL: fsqrt:
614  %0 = load i16, i16* @g, align 2
615  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
616
617; ALL: lh $[[R0:[0-9]+]]
618; ALL: fill.h $w[[W0:[0-9]+]], $[[R0]]
619; ALL: fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
620; ALL: copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
621; ALL: mtc1 $[[R1]], $f[[F0:[0-9]+]]
622; ALL: sqrt.s $f[[F1:[0-9]+]], $f[[F0]]
623
624  %sqrt = call float @llvm.sqrt.f32(float %1)
625  %2 = call i16 @llvm.convert.to.fp16.f32(float %sqrt)
626
627; ALL: mfc1 $[[R2:[0-9]+]], $f[[F1]]
628; ALL: fill.w $w[[W2:[0-9]+]], $[[R2]]
629; ALL: fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
630; ALL: copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
631
632  store i16 %2, i16* @g, align 2
633; ALL: sh $[[R3]]
634
635  ret void
636}
637
638declare float @llvm.sin.f32(float %Val)
639
640define void @fsin() {
641entry:
642; ALL-LABEL: fsin:
643  %0 = load i16, i16* @g, align 2
644  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
645
646; ALL:            lh $[[R0:[0-9]+]]
647; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
648; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
649; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
650; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
651; MIPS32-DAG:     lw $25, %call16(sinf)($gp)
652; MIPS64-N32-DAG: lw $25, %call16(sinf)($gp)
653; MIPS64-N64-DAG: ld $25, %call16(sinf)($gp)
654; ALL-DAG:        jalr $25
655
656  %sin = call float @llvm.sin.f32(float %1)
657  %2 = call i16 @llvm.convert.to.fp16.f32(float %sin)
658
659; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
660; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
661; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
662; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
663
664  store i16 %2, i16* @g, align 2
665; ALL:            sh $[[R3]]
666
667  ret void
668}
669
670declare float @llvm.cos.f32(float %Val)
671
672define void @fcos() {
673entry:
674; ALL-LABEL: fcos:
675  %0 = load i16, i16* @g, align 2
676  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
677
678; ALL:            lh $[[R0:[0-9]+]]
679; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
680; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
681; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
682; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
683; MIPS32-DAG:     lw $25, %call16(cosf)($gp)
684; MIPS64-N32-DAG: lw $25, %call16(cosf)($gp)
685; MIPS64-N64-DAG: ld $25, %call16(cosf)($gp)
686; ALL-DAG:        jalr $25
687
688  %cos = call float @llvm.cos.f32(float %1)
689  %2 = call i16 @llvm.convert.to.fp16.f32(float %cos)
690
691; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
692; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
693; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
694; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
695
696  store i16 %2, i16* @g, align 2
697; ALL:            sh $[[R3]]
698
699  ret void
700}
701
702declare float @llvm.exp.f32(float %Val)
703
704define void @fexp() {
705entry:
706; ALL-LABEL: fexp:
707  %0 = load i16, i16* @g, align 2
708  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
709; ALL:            lh $[[R0:[0-9]+]]
710; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
711; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
712; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
713; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
714; MIPS32-DAG:     lw $25, %call16(expf)($gp)
715; MIPS64-N32-DAG: lw $25, %call16(expf)($gp)
716; MIPS64-N64-DAG: ld $25, %call16(expf)($gp)
717; ALL-DAG:        jalr $25
718
719  %exp = call float @llvm.exp.f32(float %1)
720  %2 = call i16 @llvm.convert.to.fp16.f32(float %exp)
721
722; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
723; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
724; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
725; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
726
727  store i16 %2, i16* @g, align 2
728; ALL:            sh $[[R3]]
729
730  ret void
731}
732
733declare float @llvm.exp2.f32(float %Val)
734
735define void @fexp2() {
736entry:
737; ALL-LABEL: fexp2:
738  %0 = load i16, i16* @g, align 2
739  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
740
741; ALL:            lh $[[R0:[0-9]+]]
742; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
743; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
744; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
745; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
746; MIPS32-DAG:     lw $25, %call16(exp2f)($gp)
747; MIPS64-N32-DAG: lw $25, %call16(exp2f)($gp)
748; MIPS64-N64-DAG: ld $25, %call16(exp2f)($gp)
749; ALL-DAG:        jalr $25
750
751  %exp2 = call float @llvm.exp2.f32(float %1)
752  %2 = call i16 @llvm.convert.to.fp16.f32(float %exp2)
753
754; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
755; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
756; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
757; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
758
759  store i16 %2, i16* @g, align 2
760; ALL:            sh $[[R3]]
761
762  ret void
763}
764
765declare float @llvm.fma.f32(float, float, float)
766
767define void @ffma(float %b, float %c) {
768entry:
769; ALL-LABEL: ffma:
770  %0 = load i16, i16* @g, align 2
771  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
772
773; ALL:            lh $[[R0:[0-9]+]]
774; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
775; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
776; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
777; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
778; MIPS32-DAG:     lw $25, %call16(fmaf)($gp)
779; MIPS64-N32-DAG: lw $25, %call16(fmaf)($gp)
780; MIPS64-N64-DAG: ld $25, %call16(fmaf)($gp)
781; ALL-DAG:        jalr $25
782
783  %fma = call float @llvm.fma.f32(float %1, float %b, float %c)
784  %2 = call i16 @llvm.convert.to.fp16.f32(float %fma)
785
786; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
787; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
788; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
789; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
790
791  store i16 %2, i16* @g, align 2
792; ALL:            sh $[[R3]]
793
794  ret void
795}
796
797; FIXME: For MIPSR6, this should produced the maddf.s instruction. MIPSR5 cannot
798;        fuse the operation such that the intermediate result is not rounded.
799
800declare float @llvm.fmuladd.f32(float, float, float)
801
802define void @ffmuladd(float %b, float %c) {
803entry:
804; ALL-LABEL: ffmuladd:
805  %0 = load i16, i16* @g, align 2
806  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
807
808; ALL:            lh $[[R0:[0-9]+]]
809; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
810; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
811; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
812; ALL:            mtc1 $[[R1]], $f[[F0:[0-9]+]]
813; MIPS32-O32:     madd.s $f[[F1:[0-9]]], $f14, $f[[F0]], $f12
814; MIPS32-N32:     madd.s $f[[F1:[0-9]]], $f13, $f[[F0]], $f12
815; MIPS32-N64:     madd.s $f[[F1:[0-9]]], $f13, $f[[F0]], $f12
816; MIPSR6:         mul.s $f[[F2:[0-9]+]], $f[[F0]], $f12
817; MIPSR6-O32:     add.s $f[[F1:[0-9]+]], $f[[F2]], $f14
818; MIPSR6-N32:     add.s $f[[F1:[0-9]+]], $f[[F2]], $f13
819; MIPSR6-N64:     add.s $f[[F1:[0-9]+]], $f[[F2]], $f13
820
821  %fmuladd = call float @llvm.fmuladd.f32(float %1, float %b, float %c)
822  %2 = call i16 @llvm.convert.to.fp16.f32(float %fmuladd)
823
824; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
825; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
826; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
827; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
828
829  store i16 %2, i16* @g, align 2
830; ALL:            sh $[[R3]]
831
832  ret void
833}
834
835declare float @llvm.fabs.f32(float %Val)
836
837define void @ffabs() {
838entry:
839; ALL-LABEL: ffabs:
840  %0 = load i16, i16* @g, align 2
841  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
842
843; ALL:            lh $[[R0:[0-9]+]]
844; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
845; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
846; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
847; ALL:            mtc1 $[[R1]], $f[[F0:[0-9]+]]
848; ALL:            abs.s $f[[F1:[0-9]+]], $f[[F0]]
849
850  %fabs = call float @llvm.fabs.f32(float %1)
851  %2 = call i16 @llvm.convert.to.fp16.f32(float %fabs)
852
853; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
854; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
855; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
856; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
857
858  store i16 %2, i16* @g, align 2
859
860; ALL:            sh $[[R3]]
861  ret void
862}
863
864declare float @llvm.minnum.f32(float %Val, float %b)
865
866define void @fminnum(float %b) {
867entry:
868; ALL-LABEL: fminnum:
869  %0 = load i16, i16* @g, align 2
870  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
871
872; ALL:            lh $[[R0:[0-9]+]]
873; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
874; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
875; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
876; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
877; MIPS32-DAG:     lw $25, %call16(fminf)($gp)
878; MIPS64-N32-DAG: lw $25, %call16(fminf)($gp)
879; MIPS64-N64-DAG: ld $25, %call16(fminf)($gp)
880; ALL-DAG:        jalr $25
881
882  %minnum = call float @llvm.minnum.f32(float %1, float %b)
883  %2 = call i16 @llvm.convert.to.fp16.f32(float %minnum)
884
885; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
886; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
887; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
888; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
889
890  store i16 %2, i16* @g, align 2
891; ALL:            sh $[[R3]]
892
893  ret void
894}
895
896declare float @llvm.maxnum.f32(float %Val, float %b)
897
898define void @fmaxnum(float %b) {
899entry:
900; ALL-LABEL: fmaxnum:
901  %0 = load i16, i16* @g, align 2
902  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
903
904; ALL:            lh $[[R0:[0-9]+]]
905; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
906; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
907; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
908; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
909; MIPS32-DAG:     lw $25, %call16(fmaxf)($gp)
910; MIPS64-N32-DAG: lw $25, %call16(fmaxf)($gp)
911; MIPS64-N64-DAG: ld $25, %call16(fmaxf)($gp)
912; ALL-DAG:        jalr $25
913
914  %maxnum = call float @llvm.maxnum.f32(float %1, float %b)
915  %2 = call i16 @llvm.convert.to.fp16.f32(float %maxnum)
916
917; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
918; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
919; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
920; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
921
922  store i16 %2, i16* @g, align 2
923; ALL:             sh $[[R3]]
924
925  ret void
926}
927
928; This expansion of fcopysign could be done without converting f16 to float.
929
930declare float @llvm.copysign.f32(float %Val, float %b)
931
932define void @fcopysign(float %b) {
933entry:
934; ALL-LABEL: fcopysign:
935  %0 = load i16, i16* @g, align 2
936  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
937
938; ALL:            lh $[[R0:[0-9]+]]
939; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
940; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
941; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
942
943  %copysign = call float @llvm.copysign.f32(float %1, float %b)
944  %2 = call i16 @llvm.convert.to.fp16.f32(float %copysign)
945
946; ALL:            mfc1 $[[R2:[0-9]+]], $f12
947; ALL:            ext $[[R3:[0-9]+]], $3, 31, 1
948; ALL:            ins $[[R1]], $[[R3]], 31, 1
949; ALL:            fill.w $w[[W2:[0-9]+]], $[[R1]]
950; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
951; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
952
953  store i16 %2, i16* @g, align 2
954; ALL:            sh $[[R3]]
955
956  ret void
957}
958
959declare float @llvm.floor.f32(float %Val)
960
961define void @ffloor() {
962entry:
963; ALL-LABEL: ffloor:
964  %0 = load i16, i16* @g, align 2
965  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
966
967; ALL:            lh $[[R0:[0-9]+]]
968; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
969; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
970; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
971; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
972; MIPS32-DAG:     lw $25, %call16(floorf)($gp)
973; MIPS64-N32-DAG: lw $25, %call16(floorf)($gp)
974; MIPS64-N64-DAG: ld $25, %call16(floorf)($gp)
975; ALL-DAG:        jalr $25
976
977  %floor = call float @llvm.floor.f32(float %1)
978  %2 = call i16 @llvm.convert.to.fp16.f32(float %floor)
979
980; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
981; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
982; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
983; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
984
985  store i16 %2, i16* @g, align 2
986; ALL:            sh $[[R3]]
987
988  ret void
989}
990
991declare float @llvm.ceil.f32(float %Val)
992
993define void @fceil() {
994entry:
995; ALL-LABEL: fceil:
996  %0 = load i16, i16* @g, align 2
997  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
998
999; ALL:            lh $[[R0:[0-9]+]]
1000; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
1001; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
1002; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
1003; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
1004; MIPS32-DAG:     lw $25, %call16(ceilf)($gp)
1005; MIPS64-N32-DAG: lw $25, %call16(ceilf)($gp)
1006; MIPS64-N64-DAG: ld $25, %call16(ceilf)($gp)
1007; ALL-DAG:        jalr $25
1008
1009  %ceil = call float @llvm.ceil.f32(float %1)
1010  %2 = call i16 @llvm.convert.to.fp16.f32(float %ceil)
1011
1012; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
1013; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
1014; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
1015; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
1016
1017  store i16 %2, i16* @g, align 2
1018; ALL:            sh $[[R3]]
1019
1020  ret void
1021}
1022
1023declare float @llvm.trunc.f32(float %Val)
1024
1025define void @ftrunc() {
1026entry:
1027; ALL-LABEL: ftrunc:
1028  %0 = load i16, i16* @g, align 2
1029  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
1030
1031; ALL:            lh $[[R0:[0-9]+]]
1032; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
1033; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
1034; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
1035; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
1036; MIPS32-DAG:     lw $25, %call16(truncf)($gp)
1037; MIPS64-N32-DAG: lw $25, %call16(truncf)($gp)
1038; MIPS64-N64-DAG: ld $25, %call16(truncf)($gp)
1039; ALL-DAG:        jalr $25
1040
1041  %trunc = call float @llvm.trunc.f32(float %1)
1042  %2 = call i16 @llvm.convert.to.fp16.f32(float %trunc)
1043
1044; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
1045; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
1046; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
1047; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
1048
1049  store i16 %2, i16* @g, align 2
1050; ALL:            sh $[[R3]]
1051
1052  ret void
1053}
1054
1055declare float @llvm.rint.f32(float %Val)
1056
1057define void @frint() {
1058entry:
1059; ALL-LABEL: frint:
1060  %0 = load i16, i16* @g, align 2
1061  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
1062
1063; ALL:            lh $[[R0:[0-9]+]]
1064; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
1065; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
1066; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
1067; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
1068; MIPS32-DAG:     lw $25, %call16(rintf)($gp)
1069; MIPS64-N32-DAG: lw $25, %call16(rintf)($gp)
1070; MIPS64-N64-DAG: ld $25, %call16(rintf)($gp)
1071; ALL-DAG:        jalr $25
1072  %rint = call float @llvm.rint.f32(float %1)
1073  %2 = call i16 @llvm.convert.to.fp16.f32(float %rint)
1074
1075; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
1076; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
1077; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
1078; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
1079  store i16 %2, i16* @g, align 2
1080
1081; ALL:            sh $[[R3]]
1082  ret void
1083}
1084
1085declare float @llvm.nearbyint.f32(float %Val)
1086
1087define void @fnearbyint() {
1088entry:
1089; ALL-LABEL: fnearbyint:
1090  %0 = load i16, i16* @g, align 2
1091  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
1092
1093; ALL:            lh $[[R0:[0-9]+]]
1094; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
1095; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
1096; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
1097; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
1098; MIPS32-DAG:     lw $25, %call16(nearbyintf)($gp)
1099; MIPS64-N32-DAG: lw $25, %call16(nearbyintf)($gp)
1100; MIPS64-N64-DAG: ld $25, %call16(nearbyintf)($gp)
1101; ALL-DAG:        jalr $25
1102
1103  %nearbyint = call float @llvm.nearbyint.f32(float %1)
1104  %2 = call i16 @llvm.convert.to.fp16.f32(float %nearbyint)
1105
1106; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
1107; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
1108; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
1109; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
1110
1111  store i16 %2, i16* @g, align 2
1112; ALL:            sh $[[R3]]
1113
1114  ret void
1115}
1116
1117declare float @llvm.round.f32(float %Val)
1118
1119define void @fround() {
1120entry:
1121; ALL-LABEL: fround:
1122  %0 = load i16, i16* @g, align 2
1123  %1 = call float @llvm.convert.from.fp16.f32(i16 %0)
1124
1125; ALL:            lh $[[R0:[0-9]+]]
1126; ALL:            fill.h $w[[W0:[0-9]+]], $[[R0]]
1127; ALL:            fexupr.w $w[[W1:[0-9]+]], $w[[W0]]
1128; ALL:            copy_s.w $[[R1:[0-9]+]], $w[[W1]][0]
1129; ALL-DAG:        mtc1 $[[R1]], $f[[F0:[0-9]+]]
1130; MIPS32-DAG:     lw $25, %call16(roundf)($gp)
1131; MIPS64-N32-DAG: lw $25, %call16(roundf)($gp)
1132; MIPS64-N64-DAG: ld $25, %call16(roundf)($gp)
1133; ALL-DAG:        jalr $25
1134
1135  %round = call float @llvm.round.f32(float %1)
1136  %2 = call i16 @llvm.convert.to.fp16.f32(float %round)
1137
1138; ALL:            mfc1 $[[R2:[0-9]+]], $f[[F1]]
1139; ALL:            fill.w $w[[W2:[0-9]+]], $[[R2]]
1140; ALL:            fexdo.h $w[[W3:[0-9]+]], $w[[W2]], $w[[W2]]
1141; ALL:            copy_u.h $[[R3:[0-9]+]], $w[[W3]][0]
1142
1143  store i16 %2, i16* @g, align 2
1144; ALL:            sh $[[R3]]
1145
1146  ret void
1147}
1148