]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGen/Mips/msa/f16-llvm-ir.ll
Vendor import of llvm trunk r290819:
[FreeBSD/FreeBSD.git] / test / CodeGen / Mips / msa / f16-llvm-ir.ll
1 ; RUN: llc -relocation-model=pic -march=mipsel -mcpu=mips32r5 \
2 ; RUN:     -mattr=+fp64,+msa < %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 -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 -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 < %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 -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 -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
26 declare float @k2(half *)
27
28 define void @f3(i16 %b) {
29 entry:
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
47 define 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
74 define void @fadd_f64() {
75 entry:
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
115 define i32 @ffptoui() {
116 entry:
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
189 define i32 @ffptosi() {
190 entry:
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
213 define void @uitofp(i32 %a) {
214 entry:
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: ld $[[R3:[0-9]+]], %got_disp(h)
238 ; MIPS64-N32: lw $[[R3:[0-9]+]], %got_disp(h)
239 ; MIPS64:     dmfc1 $[[R1:[0-9]+]], $f[[F2]]
240 ; MIPS64:     fill.d $w[[W0:[0-9]+]], $[[R1]]
241
242 ; ALL:        fexdo.w $w[[W1:[0-9]+]], $w[[W0]], $w[[W0]]
243 ; ALL:        fexdo.h $w[[W2:[0-9]+]], $w[[W1]], $w[[W1]]
244
245 ; MIPS32:     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
258 define void @fadd() {
259 entry:
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
288 declare float @llvm.convert.from.fp16.f32(i16)
289
290 ; Function Attrs: nounwind readnone
291 declare i16 @llvm.convert.to.fp16.f32(float)
292
293 ; Function Attrs: nounwind
294 define void @fsub() {
295 entry:
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
324 define void @fmult() {
325 entry:
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
355 define void @fdiv() {
356 entry:
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
385 define void @frem() {
386 entry:
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
421 define void @fcmp() {
422 entry:
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
451 declare float @llvm.powi.f32(float, i32)
452
453 define void @fpowi() {
454 entry:
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
481 define void @fpowi_var(i32 %var) {
482 entry:
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
512 declare float @llvm.pow.f32(float %Val, float %power)
513
514 define void @fpow(float %var) {
515 entry:
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
545 declare float @llvm.log2.f32(float %Val)
546
547 define void @flog2() {
548 entry:
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
577 declare float @llvm.log10.f32(float %Val)
578
579 define void @flog10() {
580 entry:
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
609 declare float @llvm.sqrt.f32(float %Val)
610
611 define void @fsqrt() {
612 entry:
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
638 declare float @llvm.sin.f32(float %Val)
639
640 define void @fsin() {
641 entry:
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
670 declare float @llvm.cos.f32(float %Val)
671
672 define void @fcos() {
673 entry:
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
702 declare float @llvm.exp.f32(float %Val)
703
704 define void @fexp() {
705 entry:
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
733 declare float @llvm.exp2.f32(float %Val)
734
735 define void @fexp2() {
736 entry:
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
765 declare float @llvm.fma.f32(float, float, float)
766
767 define void @ffma(float %b, float %c) {
768 entry:
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
800 declare float @llvm.fmuladd.f32(float, float, float)
801
802 define void @ffmuladd(float %b, float %c) {
803 entry:
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
835 declare float @llvm.fabs.f32(float %Val)
836
837 define void @ffabs() {
838 entry:
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
864 declare float @llvm.minnum.f32(float %Val, float %b)
865
866 define void @fminnum(float %b) {
867 entry:
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
896 declare float @llvm.maxnum.f32(float %Val, float %b)
897
898 define void @fmaxnum(float %b) {
899 entry:
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
930 declare float @llvm.copysign.f32(float %Val, float %b)
931
932 define void @fcopysign(float %b) {
933 entry:
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
959 declare float @llvm.floor.f32(float %Val)
960
961 define void @ffloor() {
962 entry:
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
991 declare float @llvm.ceil.f32(float %Val)
992
993 define void @fceil() {
994 entry:
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
1023 declare float @llvm.trunc.f32(float %Val)
1024
1025 define void @ftrunc() {
1026 entry:
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
1055 declare float @llvm.rint.f32(float %Val)
1056
1057 define void @frint() {
1058 entry:
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
1085 declare float @llvm.nearbyint.f32(float %Val)
1086
1087 define void @fnearbyint() {
1088 entry:
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
1117 declare float @llvm.round.f32(float %Val)
1118
1119 define void @fround() {
1120 entry:
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 }