Home | History | Annotate | Download | only in msa
      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 
     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-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 
    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 }
   1148