xref: /openbmc/qemu/target/riscv/fpu_helper.c (revision 3ceeb19a)
1 /*
2  * RISC-V FPU Emulation Helpers for QEMU.
3  *
4  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2 or later, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include "cpu.h"
21 #include "qemu/host-utils.h"
22 #include "exec/exec-all.h"
23 #include "exec/helper-proto.h"
24 #include "fpu/softfloat.h"
25 #include "internals.h"
26 
27 target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
28 {
29     int soft = get_float_exception_flags(&env->fp_status);
30     target_ulong hard = 0;
31 
32     hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
33     hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
34     hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
35     hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
36     hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
37 
38     return hard;
39 }
40 
41 void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
42 {
43     int soft = 0;
44 
45     soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
46     soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
47     soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
48     soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
49     soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
50 
51     set_float_exception_flags(soft, &env->fp_status);
52 }
53 
54 void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
55 {
56     int softrm;
57 
58     if (rm == RISCV_FRM_DYN) {
59         rm = env->frm;
60     }
61     switch (rm) {
62     case RISCV_FRM_RNE:
63         softrm = float_round_nearest_even;
64         break;
65     case RISCV_FRM_RTZ:
66         softrm = float_round_to_zero;
67         break;
68     case RISCV_FRM_RDN:
69         softrm = float_round_down;
70         break;
71     case RISCV_FRM_RUP:
72         softrm = float_round_up;
73         break;
74     case RISCV_FRM_RMM:
75         softrm = float_round_ties_away;
76         break;
77     default:
78         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
79     }
80 
81     set_float_rounding_mode(softrm, &env->fp_status);
82 }
83 
84 void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
85 {
86     int softrm;
87 
88     /* Always validate frm, even if rm != DYN. */
89     if (unlikely(env->frm >= 5)) {
90         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
91     }
92     if (rm == RISCV_FRM_DYN) {
93         rm = env->frm;
94     }
95     switch (rm) {
96     case RISCV_FRM_RNE:
97         softrm = float_round_nearest_even;
98         break;
99     case RISCV_FRM_RTZ:
100         softrm = float_round_to_zero;
101         break;
102     case RISCV_FRM_RDN:
103         softrm = float_round_down;
104         break;
105     case RISCV_FRM_RUP:
106         softrm = float_round_up;
107         break;
108     case RISCV_FRM_RMM:
109         softrm = float_round_ties_away;
110         break;
111     case RISCV_FRM_ROD:
112         softrm = float_round_to_odd;
113         break;
114     default:
115         g_assert_not_reached();
116     }
117 
118     set_float_rounding_mode(softrm, &env->fp_status);
119 }
120 
121 void helper_set_rod_rounding_mode(CPURISCVState *env)
122 {
123     set_float_rounding_mode(float_round_to_odd, &env->fp_status);
124 }
125 
126 static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
127                            uint64_t rs3, int flags)
128 {
129     float16 frs1 = check_nanbox_h(env, rs1);
130     float16 frs2 = check_nanbox_h(env, rs2);
131     float16 frs3 = check_nanbox_h(env, rs3);
132     return nanbox_h(env, float16_muladd(frs1, frs2, frs3, flags,
133                                         &env->fp_status));
134 }
135 
136 static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
137                            uint64_t rs3, int flags)
138 {
139     float32 frs1 = check_nanbox_s(env, rs1);
140     float32 frs2 = check_nanbox_s(env, rs2);
141     float32 frs3 = check_nanbox_s(env, rs3);
142     return nanbox_s(env, float32_muladd(frs1, frs2, frs3, flags,
143                                         &env->fp_status));
144 }
145 
146 uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
147                         uint64_t frs3)
148 {
149     return do_fmadd_s(env, frs1, frs2, frs3, 0);
150 }
151 
152 uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
153                         uint64_t frs3)
154 {
155     return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
156 }
157 
158 uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
159                         uint64_t frs3)
160 {
161     return do_fmadd_h(env, frs1, frs2, frs3, 0);
162 }
163 
164 uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
165                         uint64_t frs3)
166 {
167     return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_c);
168 }
169 
170 uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
171                         uint64_t frs3)
172 {
173     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c,
174                           &env->fp_status);
175 }
176 
177 uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
178                         uint64_t frs3)
179 {
180     return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c);
181 }
182 
183 uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
184                          uint64_t frs3)
185 {
186     return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_product);
187 }
188 
189 uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
190                          uint64_t frs3)
191 {
192     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_product,
193                           &env->fp_status);
194 }
195 
196 uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
197                          uint64_t frs3)
198 {
199     return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product);
200 }
201 
202 uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
203                          uint64_t frs3)
204 {
205     return do_fmadd_s(env, frs1, frs2, frs3,
206                       float_muladd_negate_c | float_muladd_negate_product);
207 }
208 
209 uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
210                          uint64_t frs3)
211 {
212     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c |
213                           float_muladd_negate_product, &env->fp_status);
214 }
215 
216 uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
217                          uint64_t frs3)
218 {
219     return do_fmadd_h(env, frs1, frs2, frs3,
220                       float_muladd_negate_c | float_muladd_negate_product);
221 }
222 
223 uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
224 {
225     float32 frs1 = check_nanbox_s(env, rs1);
226     float32 frs2 = check_nanbox_s(env, rs2);
227     return nanbox_s(env, float32_add(frs1, frs2, &env->fp_status));
228 }
229 
230 uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
231 {
232     float32 frs1 = check_nanbox_s(env, rs1);
233     float32 frs2 = check_nanbox_s(env, rs2);
234     return nanbox_s(env, float32_sub(frs1, frs2, &env->fp_status));
235 }
236 
237 uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
238 {
239     float32 frs1 = check_nanbox_s(env, rs1);
240     float32 frs2 = check_nanbox_s(env, rs2);
241     return nanbox_s(env, float32_mul(frs1, frs2, &env->fp_status));
242 }
243 
244 uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
245 {
246     float32 frs1 = check_nanbox_s(env, rs1);
247     float32 frs2 = check_nanbox_s(env, rs2);
248     return nanbox_s(env, float32_div(frs1, frs2, &env->fp_status));
249 }
250 
251 uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
252 {
253     float32 frs1 = check_nanbox_s(env, rs1);
254     float32 frs2 = check_nanbox_s(env, rs2);
255     return nanbox_s(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
256                     float32_minnum(frs1, frs2, &env->fp_status) :
257                     float32_minimum_number(frs1, frs2, &env->fp_status));
258 }
259 
260 uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
261 {
262     float32 frs1 = check_nanbox_s(env, rs1);
263     float32 frs2 = check_nanbox_s(env, rs2);
264     return nanbox_s(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
265                     float32_maxnum(frs1, frs2, &env->fp_status) :
266                     float32_maximum_number(frs1, frs2, &env->fp_status));
267 }
268 
269 uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
270 {
271     float32 frs1 = check_nanbox_s(env, rs1);
272     return nanbox_s(env, float32_sqrt(frs1, &env->fp_status));
273 }
274 
275 target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
276 {
277     float32 frs1 = check_nanbox_s(env, rs1);
278     float32 frs2 = check_nanbox_s(env, rs2);
279     return float32_le(frs1, frs2, &env->fp_status);
280 }
281 
282 target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
283 {
284     float32 frs1 = check_nanbox_s(env, rs1);
285     float32 frs2 = check_nanbox_s(env, rs2);
286     return float32_lt(frs1, frs2, &env->fp_status);
287 }
288 
289 target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
290 {
291     float32 frs1 = check_nanbox_s(env, rs1);
292     float32 frs2 = check_nanbox_s(env, rs2);
293     return float32_eq_quiet(frs1, frs2, &env->fp_status);
294 }
295 
296 target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)
297 {
298     float32 frs1 = check_nanbox_s(env, rs1);
299     return float32_to_int32(frs1, &env->fp_status);
300 }
301 
302 target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
303 {
304     float32 frs1 = check_nanbox_s(env, rs1);
305     return (int32_t)float32_to_uint32(frs1, &env->fp_status);
306 }
307 
308 target_ulong helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
309 {
310     float32 frs1 = check_nanbox_s(env, rs1);
311     return float32_to_int64(frs1, &env->fp_status);
312 }
313 
314 target_ulong helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
315 {
316     float32 frs1 = check_nanbox_s(env, rs1);
317     return float32_to_uint64(frs1, &env->fp_status);
318 }
319 
320 uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1)
321 {
322     return nanbox_s(env, int32_to_float32((int32_t)rs1, &env->fp_status));
323 }
324 
325 uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
326 {
327     return nanbox_s(env, uint32_to_float32((uint32_t)rs1, &env->fp_status));
328 }
329 
330 uint64_t helper_fcvt_s_l(CPURISCVState *env, target_ulong rs1)
331 {
332     return nanbox_s(env, int64_to_float32(rs1, &env->fp_status));
333 }
334 
335 uint64_t helper_fcvt_s_lu(CPURISCVState *env, target_ulong rs1)
336 {
337     return nanbox_s(env, uint64_to_float32(rs1, &env->fp_status));
338 }
339 
340 target_ulong helper_fclass_s(CPURISCVState *env, uint64_t rs1)
341 {
342     float32 frs1 = check_nanbox_s(env, rs1);
343     return fclass_s(frs1);
344 }
345 
346 uint64_t helper_fadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
347 {
348     return float64_add(frs1, frs2, &env->fp_status);
349 }
350 
351 uint64_t helper_fsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
352 {
353     return float64_sub(frs1, frs2, &env->fp_status);
354 }
355 
356 uint64_t helper_fmul_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
357 {
358     return float64_mul(frs1, frs2, &env->fp_status);
359 }
360 
361 uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
362 {
363     return float64_div(frs1, frs2, &env->fp_status);
364 }
365 
366 uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
367 {
368     return env->priv_ver < PRIV_VERSION_1_11_0 ?
369             float64_minnum(frs1, frs2, &env->fp_status) :
370             float64_minimum_number(frs1, frs2, &env->fp_status);
371 }
372 
373 uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
374 {
375     return env->priv_ver < PRIV_VERSION_1_11_0 ?
376             float64_maxnum(frs1, frs2, &env->fp_status) :
377             float64_maximum_number(frs1, frs2, &env->fp_status);
378 }
379 
380 uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
381 {
382     return nanbox_s(env, float64_to_float32(rs1, &env->fp_status));
383 }
384 
385 uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)
386 {
387     float32 frs1 = check_nanbox_s(env, rs1);
388     return float32_to_float64(frs1, &env->fp_status);
389 }
390 
391 uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)
392 {
393     return float64_sqrt(frs1, &env->fp_status);
394 }
395 
396 target_ulong helper_fle_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
397 {
398     return float64_le(frs1, frs2, &env->fp_status);
399 }
400 
401 target_ulong helper_flt_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
402 {
403     return float64_lt(frs1, frs2, &env->fp_status);
404 }
405 
406 target_ulong helper_feq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
407 {
408     return float64_eq_quiet(frs1, frs2, &env->fp_status);
409 }
410 
411 target_ulong helper_fcvt_w_d(CPURISCVState *env, uint64_t frs1)
412 {
413     return float64_to_int32(frs1, &env->fp_status);
414 }
415 
416 target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
417 {
418     return (int32_t)float64_to_uint32(frs1, &env->fp_status);
419 }
420 
421 target_ulong helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
422 {
423     return float64_to_int64(frs1, &env->fp_status);
424 }
425 
426 target_ulong helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
427 {
428     return float64_to_uint64(frs1, &env->fp_status);
429 }
430 
431 uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1)
432 {
433     return int32_to_float64((int32_t)rs1, &env->fp_status);
434 }
435 
436 uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
437 {
438     return uint32_to_float64((uint32_t)rs1, &env->fp_status);
439 }
440 
441 uint64_t helper_fcvt_d_l(CPURISCVState *env, target_ulong rs1)
442 {
443     return int64_to_float64(rs1, &env->fp_status);
444 }
445 
446 uint64_t helper_fcvt_d_lu(CPURISCVState *env, target_ulong rs1)
447 {
448     return uint64_to_float64(rs1, &env->fp_status);
449 }
450 
451 target_ulong helper_fclass_d(uint64_t frs1)
452 {
453     return fclass_d(frs1);
454 }
455 
456 uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
457 {
458     float16 frs1 = check_nanbox_h(env, rs1);
459     float16 frs2 = check_nanbox_h(env, rs2);
460     return nanbox_h(env, float16_add(frs1, frs2, &env->fp_status));
461 }
462 
463 uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
464 {
465     float16 frs1 = check_nanbox_h(env, rs1);
466     float16 frs2 = check_nanbox_h(env, rs2);
467     return nanbox_h(env, float16_sub(frs1, frs2, &env->fp_status));
468 }
469 
470 uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
471 {
472     float16 frs1 = check_nanbox_h(env, rs1);
473     float16 frs2 = check_nanbox_h(env, rs2);
474     return nanbox_h(env, float16_mul(frs1, frs2, &env->fp_status));
475 }
476 
477 uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
478 {
479     float16 frs1 = check_nanbox_h(env, rs1);
480     float16 frs2 = check_nanbox_h(env, rs2);
481     return nanbox_h(env, float16_div(frs1, frs2, &env->fp_status));
482 }
483 
484 uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
485 {
486     float16 frs1 = check_nanbox_h(env, rs1);
487     float16 frs2 = check_nanbox_h(env, rs2);
488     return nanbox_h(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
489                     float16_minnum(frs1, frs2, &env->fp_status) :
490                     float16_minimum_number(frs1, frs2, &env->fp_status));
491 }
492 
493 uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
494 {
495     float16 frs1 = check_nanbox_h(env, rs1);
496     float16 frs2 = check_nanbox_h(env, rs2);
497     return nanbox_h(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
498                     float16_maxnum(frs1, frs2, &env->fp_status) :
499                     float16_maximum_number(frs1, frs2, &env->fp_status));
500 }
501 
502 uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
503 {
504     float16 frs1 = check_nanbox_h(env, rs1);
505     return nanbox_h(env, float16_sqrt(frs1, &env->fp_status));
506 }
507 
508 target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
509 {
510     float16 frs1 = check_nanbox_h(env, rs1);
511     float16 frs2 = check_nanbox_h(env, rs2);
512     return float16_le(frs1, frs2, &env->fp_status);
513 }
514 
515 target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
516 {
517     float16 frs1 = check_nanbox_h(env, rs1);
518     float16 frs2 = check_nanbox_h(env, rs2);
519     return float16_lt(frs1, frs2, &env->fp_status);
520 }
521 
522 target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
523 {
524     float16 frs1 = check_nanbox_h(env, rs1);
525     float16 frs2 = check_nanbox_h(env, rs2);
526     return float16_eq_quiet(frs1, frs2, &env->fp_status);
527 }
528 
529 target_ulong helper_fclass_h(CPURISCVState *env, uint64_t rs1)
530 {
531     float16 frs1 = check_nanbox_h(env, rs1);
532     return fclass_h(frs1);
533 }
534 
535 target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
536 {
537     float16 frs1 = check_nanbox_h(env, rs1);
538     return float16_to_int32(frs1, &env->fp_status);
539 }
540 
541 target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1)
542 {
543     float16 frs1 = check_nanbox_h(env, rs1);
544     return (int32_t)float16_to_uint32(frs1, &env->fp_status);
545 }
546 
547 target_ulong helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1)
548 {
549     float16 frs1 = check_nanbox_h(env, rs1);
550     return float16_to_int64(frs1, &env->fp_status);
551 }
552 
553 target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1)
554 {
555     float16 frs1 = check_nanbox_h(env, rs1);
556     return float16_to_uint64(frs1, &env->fp_status);
557 }
558 
559 uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1)
560 {
561     return nanbox_h(env, int32_to_float16((int32_t)rs1, &env->fp_status));
562 }
563 
564 uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1)
565 {
566     return nanbox_h(env, uint32_to_float16((uint32_t)rs1, &env->fp_status));
567 }
568 
569 uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1)
570 {
571     return nanbox_h(env, int64_to_float16(rs1, &env->fp_status));
572 }
573 
574 uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1)
575 {
576     return nanbox_h(env, uint64_to_float16(rs1, &env->fp_status));
577 }
578 
579 uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1)
580 {
581     float32 frs1 = check_nanbox_s(env, rs1);
582     return nanbox_h(env, float32_to_float16(frs1, true, &env->fp_status));
583 }
584 
585 uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1)
586 {
587     float16 frs1 = check_nanbox_h(env, rs1);
588     return nanbox_s(env, float16_to_float32(frs1, true, &env->fp_status));
589 }
590 
591 uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1)
592 {
593     return nanbox_h(env, float64_to_float16(rs1, true, &env->fp_status));
594 }
595 
596 uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
597 {
598     float16 frs1 = check_nanbox_h(env, rs1);
599     return float16_to_float64(frs1, true, &env->fp_status);
600 }
601