xref: /qemu/target/riscv/fpu_helper.c (revision 29b62a10)
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 static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
122                            uint64_t rs3, int flags)
123 {
124     float16 frs1 = check_nanbox_h(env, rs1);
125     float16 frs2 = check_nanbox_h(env, rs2);
126     float16 frs3 = check_nanbox_h(env, rs3);
127     return nanbox_h(env, float16_muladd(frs1, frs2, frs3, flags,
128                                         &env->fp_status));
129 }
130 
131 static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
132                            uint64_t rs3, int flags)
133 {
134     float32 frs1 = check_nanbox_s(env, rs1);
135     float32 frs2 = check_nanbox_s(env, rs2);
136     float32 frs3 = check_nanbox_s(env, rs3);
137     return nanbox_s(env, float32_muladd(frs1, frs2, frs3, flags,
138                                         &env->fp_status));
139 }
140 
141 uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
142                         uint64_t frs3)
143 {
144     return do_fmadd_s(env, frs1, frs2, frs3, 0);
145 }
146 
147 uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
148                         uint64_t frs3)
149 {
150     return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
151 }
152 
153 uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
154                         uint64_t frs3)
155 {
156     return do_fmadd_h(env, frs1, frs2, frs3, 0);
157 }
158 
159 uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
160                         uint64_t frs3)
161 {
162     return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_c);
163 }
164 
165 uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
166                         uint64_t frs3)
167 {
168     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c,
169                           &env->fp_status);
170 }
171 
172 uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
173                         uint64_t frs3)
174 {
175     return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c);
176 }
177 
178 uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
179                          uint64_t frs3)
180 {
181     return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_product);
182 }
183 
184 uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
185                          uint64_t frs3)
186 {
187     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_product,
188                           &env->fp_status);
189 }
190 
191 uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
192                          uint64_t frs3)
193 {
194     return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product);
195 }
196 
197 uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
198                          uint64_t frs3)
199 {
200     return do_fmadd_s(env, frs1, frs2, frs3,
201                       float_muladd_negate_c | float_muladd_negate_product);
202 }
203 
204 uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
205                          uint64_t frs3)
206 {
207     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c |
208                           float_muladd_negate_product, &env->fp_status);
209 }
210 
211 uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
212                          uint64_t frs3)
213 {
214     return do_fmadd_h(env, frs1, frs2, frs3,
215                       float_muladd_negate_c | float_muladd_negate_product);
216 }
217 
218 uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
219 {
220     float32 frs1 = check_nanbox_s(env, rs1);
221     float32 frs2 = check_nanbox_s(env, rs2);
222     return nanbox_s(env, float32_add(frs1, frs2, &env->fp_status));
223 }
224 
225 uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
226 {
227     float32 frs1 = check_nanbox_s(env, rs1);
228     float32 frs2 = check_nanbox_s(env, rs2);
229     return nanbox_s(env, float32_sub(frs1, frs2, &env->fp_status));
230 }
231 
232 uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
233 {
234     float32 frs1 = check_nanbox_s(env, rs1);
235     float32 frs2 = check_nanbox_s(env, rs2);
236     return nanbox_s(env, float32_mul(frs1, frs2, &env->fp_status));
237 }
238 
239 uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
240 {
241     float32 frs1 = check_nanbox_s(env, rs1);
242     float32 frs2 = check_nanbox_s(env, rs2);
243     return nanbox_s(env, float32_div(frs1, frs2, &env->fp_status));
244 }
245 
246 uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
247 {
248     float32 frs1 = check_nanbox_s(env, rs1);
249     float32 frs2 = check_nanbox_s(env, rs2);
250     return nanbox_s(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
251                     float32_minnum(frs1, frs2, &env->fp_status) :
252                     float32_minimum_number(frs1, frs2, &env->fp_status));
253 }
254 
255 uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
256 {
257     float32 frs1 = check_nanbox_s(env, rs1);
258     float32 frs2 = check_nanbox_s(env, rs2);
259     return nanbox_s(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
260                     float32_maxnum(frs1, frs2, &env->fp_status) :
261                     float32_maximum_number(frs1, frs2, &env->fp_status));
262 }
263 
264 uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
265 {
266     float32 frs1 = check_nanbox_s(env, rs1);
267     return nanbox_s(env, float32_sqrt(frs1, &env->fp_status));
268 }
269 
270 target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
271 {
272     float32 frs1 = check_nanbox_s(env, rs1);
273     float32 frs2 = check_nanbox_s(env, rs2);
274     return float32_le(frs1, frs2, &env->fp_status);
275 }
276 
277 target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
278 {
279     float32 frs1 = check_nanbox_s(env, rs1);
280     float32 frs2 = check_nanbox_s(env, rs2);
281     return float32_lt(frs1, frs2, &env->fp_status);
282 }
283 
284 target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
285 {
286     float32 frs1 = check_nanbox_s(env, rs1);
287     float32 frs2 = check_nanbox_s(env, rs2);
288     return float32_eq_quiet(frs1, frs2, &env->fp_status);
289 }
290 
291 target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)
292 {
293     float32 frs1 = check_nanbox_s(env, rs1);
294     return float32_to_int32(frs1, &env->fp_status);
295 }
296 
297 target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
298 {
299     float32 frs1 = check_nanbox_s(env, rs1);
300     return (int32_t)float32_to_uint32(frs1, &env->fp_status);
301 }
302 
303 target_ulong helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
304 {
305     float32 frs1 = check_nanbox_s(env, rs1);
306     return float32_to_int64(frs1, &env->fp_status);
307 }
308 
309 target_ulong helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
310 {
311     float32 frs1 = check_nanbox_s(env, rs1);
312     return float32_to_uint64(frs1, &env->fp_status);
313 }
314 
315 uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1)
316 {
317     return nanbox_s(env, int32_to_float32((int32_t)rs1, &env->fp_status));
318 }
319 
320 uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
321 {
322     return nanbox_s(env, uint32_to_float32((uint32_t)rs1, &env->fp_status));
323 }
324 
325 uint64_t helper_fcvt_s_l(CPURISCVState *env, target_ulong rs1)
326 {
327     return nanbox_s(env, int64_to_float32(rs1, &env->fp_status));
328 }
329 
330 uint64_t helper_fcvt_s_lu(CPURISCVState *env, target_ulong rs1)
331 {
332     return nanbox_s(env, uint64_to_float32(rs1, &env->fp_status));
333 }
334 
335 target_ulong helper_fclass_s(CPURISCVState *env, uint64_t rs1)
336 {
337     float32 frs1 = check_nanbox_s(env, rs1);
338     return fclass_s(frs1);
339 }
340 
341 uint64_t helper_fadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
342 {
343     return float64_add(frs1, frs2, &env->fp_status);
344 }
345 
346 uint64_t helper_fsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
347 {
348     return float64_sub(frs1, frs2, &env->fp_status);
349 }
350 
351 uint64_t helper_fmul_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
352 {
353     return float64_mul(frs1, frs2, &env->fp_status);
354 }
355 
356 uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
357 {
358     return float64_div(frs1, frs2, &env->fp_status);
359 }
360 
361 uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
362 {
363     return env->priv_ver < PRIV_VERSION_1_11_0 ?
364             float64_minnum(frs1, frs2, &env->fp_status) :
365             float64_minimum_number(frs1, frs2, &env->fp_status);
366 }
367 
368 uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
369 {
370     return env->priv_ver < PRIV_VERSION_1_11_0 ?
371             float64_maxnum(frs1, frs2, &env->fp_status) :
372             float64_maximum_number(frs1, frs2, &env->fp_status);
373 }
374 
375 uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
376 {
377     return nanbox_s(env, float64_to_float32(rs1, &env->fp_status));
378 }
379 
380 uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)
381 {
382     float32 frs1 = check_nanbox_s(env, rs1);
383     return float32_to_float64(frs1, &env->fp_status);
384 }
385 
386 uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)
387 {
388     return float64_sqrt(frs1, &env->fp_status);
389 }
390 
391 target_ulong helper_fle_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
392 {
393     return float64_le(frs1, frs2, &env->fp_status);
394 }
395 
396 target_ulong helper_flt_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
397 {
398     return float64_lt(frs1, frs2, &env->fp_status);
399 }
400 
401 target_ulong helper_feq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
402 {
403     return float64_eq_quiet(frs1, frs2, &env->fp_status);
404 }
405 
406 target_ulong helper_fcvt_w_d(CPURISCVState *env, uint64_t frs1)
407 {
408     return float64_to_int32(frs1, &env->fp_status);
409 }
410 
411 target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
412 {
413     return (int32_t)float64_to_uint32(frs1, &env->fp_status);
414 }
415 
416 target_ulong helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
417 {
418     return float64_to_int64(frs1, &env->fp_status);
419 }
420 
421 target_ulong helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
422 {
423     return float64_to_uint64(frs1, &env->fp_status);
424 }
425 
426 uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1)
427 {
428     return int32_to_float64((int32_t)rs1, &env->fp_status);
429 }
430 
431 uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
432 {
433     return uint32_to_float64((uint32_t)rs1, &env->fp_status);
434 }
435 
436 uint64_t helper_fcvt_d_l(CPURISCVState *env, target_ulong rs1)
437 {
438     return int64_to_float64(rs1, &env->fp_status);
439 }
440 
441 uint64_t helper_fcvt_d_lu(CPURISCVState *env, target_ulong rs1)
442 {
443     return uint64_to_float64(rs1, &env->fp_status);
444 }
445 
446 target_ulong helper_fclass_d(uint64_t frs1)
447 {
448     return fclass_d(frs1);
449 }
450 
451 uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
452 {
453     float16 frs1 = check_nanbox_h(env, rs1);
454     float16 frs2 = check_nanbox_h(env, rs2);
455     return nanbox_h(env, float16_add(frs1, frs2, &env->fp_status));
456 }
457 
458 uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
459 {
460     float16 frs1 = check_nanbox_h(env, rs1);
461     float16 frs2 = check_nanbox_h(env, rs2);
462     return nanbox_h(env, float16_sub(frs1, frs2, &env->fp_status));
463 }
464 
465 uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
466 {
467     float16 frs1 = check_nanbox_h(env, rs1);
468     float16 frs2 = check_nanbox_h(env, rs2);
469     return nanbox_h(env, float16_mul(frs1, frs2, &env->fp_status));
470 }
471 
472 uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
473 {
474     float16 frs1 = check_nanbox_h(env, rs1);
475     float16 frs2 = check_nanbox_h(env, rs2);
476     return nanbox_h(env, float16_div(frs1, frs2, &env->fp_status));
477 }
478 
479 uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
480 {
481     float16 frs1 = check_nanbox_h(env, rs1);
482     float16 frs2 = check_nanbox_h(env, rs2);
483     return nanbox_h(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
484                     float16_minnum(frs1, frs2, &env->fp_status) :
485                     float16_minimum_number(frs1, frs2, &env->fp_status));
486 }
487 
488 uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
489 {
490     float16 frs1 = check_nanbox_h(env, rs1);
491     float16 frs2 = check_nanbox_h(env, rs2);
492     return nanbox_h(env, env->priv_ver < PRIV_VERSION_1_11_0 ?
493                     float16_maxnum(frs1, frs2, &env->fp_status) :
494                     float16_maximum_number(frs1, frs2, &env->fp_status));
495 }
496 
497 uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
498 {
499     float16 frs1 = check_nanbox_h(env, rs1);
500     return nanbox_h(env, float16_sqrt(frs1, &env->fp_status));
501 }
502 
503 target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
504 {
505     float16 frs1 = check_nanbox_h(env, rs1);
506     float16 frs2 = check_nanbox_h(env, rs2);
507     return float16_le(frs1, frs2, &env->fp_status);
508 }
509 
510 target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
511 {
512     float16 frs1 = check_nanbox_h(env, rs1);
513     float16 frs2 = check_nanbox_h(env, rs2);
514     return float16_lt(frs1, frs2, &env->fp_status);
515 }
516 
517 target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
518 {
519     float16 frs1 = check_nanbox_h(env, rs1);
520     float16 frs2 = check_nanbox_h(env, rs2);
521     return float16_eq_quiet(frs1, frs2, &env->fp_status);
522 }
523 
524 target_ulong helper_fclass_h(CPURISCVState *env, uint64_t rs1)
525 {
526     float16 frs1 = check_nanbox_h(env, rs1);
527     return fclass_h(frs1);
528 }
529 
530 target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
531 {
532     float16 frs1 = check_nanbox_h(env, rs1);
533     return float16_to_int32(frs1, &env->fp_status);
534 }
535 
536 target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1)
537 {
538     float16 frs1 = check_nanbox_h(env, rs1);
539     return (int32_t)float16_to_uint32(frs1, &env->fp_status);
540 }
541 
542 target_ulong helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1)
543 {
544     float16 frs1 = check_nanbox_h(env, rs1);
545     return float16_to_int64(frs1, &env->fp_status);
546 }
547 
548 target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1)
549 {
550     float16 frs1 = check_nanbox_h(env, rs1);
551     return float16_to_uint64(frs1, &env->fp_status);
552 }
553 
554 uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1)
555 {
556     return nanbox_h(env, int32_to_float16((int32_t)rs1, &env->fp_status));
557 }
558 
559 uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1)
560 {
561     return nanbox_h(env, uint32_to_float16((uint32_t)rs1, &env->fp_status));
562 }
563 
564 uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1)
565 {
566     return nanbox_h(env, int64_to_float16(rs1, &env->fp_status));
567 }
568 
569 uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1)
570 {
571     return nanbox_h(env, uint64_to_float16(rs1, &env->fp_status));
572 }
573 
574 uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1)
575 {
576     float32 frs1 = check_nanbox_s(env, rs1);
577     return nanbox_h(env, float32_to_float16(frs1, true, &env->fp_status));
578 }
579 
580 uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1)
581 {
582     float16 frs1 = check_nanbox_h(env, rs1);
583     return nanbox_s(env, float16_to_float32(frs1, true, &env->fp_status));
584 }
585 
586 uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1)
587 {
588     return nanbox_h(env, float64_to_float16(rs1, true, &env->fp_status));
589 }
590 
591 uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
592 {
593     float16 frs1 = check_nanbox_h(env, rs1);
594     return float16_to_float64(frs1, true, &env->fp_status);
595 }
596