xref: /qemu/target/riscv/fpu_helper.c (revision f798f1e29be6066feafa2a88aa94441695339e0a)
1*f798f1e2SMichael Clark /*
2*f798f1e2SMichael Clark  * RISC-V FPU Emulation Helpers for QEMU.
3*f798f1e2SMichael Clark  *
4*f798f1e2SMichael Clark  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5*f798f1e2SMichael Clark  *
6*f798f1e2SMichael Clark  * This program is free software; you can redistribute it and/or modify it
7*f798f1e2SMichael Clark  * under the terms and conditions of the GNU General Public License,
8*f798f1e2SMichael Clark  * version 2 or later, as published by the Free Software Foundation.
9*f798f1e2SMichael Clark  *
10*f798f1e2SMichael Clark  * This program is distributed in the hope it will be useful, but WITHOUT
11*f798f1e2SMichael Clark  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12*f798f1e2SMichael Clark  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13*f798f1e2SMichael Clark  * more details.
14*f798f1e2SMichael Clark  *
15*f798f1e2SMichael Clark  * You should have received a copy of the GNU General Public License along with
16*f798f1e2SMichael Clark  * this program.  If not, see <http://www.gnu.org/licenses/>.
17*f798f1e2SMichael Clark  */
18*f798f1e2SMichael Clark 
19*f798f1e2SMichael Clark #include "qemu/osdep.h"
20*f798f1e2SMichael Clark #include <stdlib.h>
21*f798f1e2SMichael Clark #include "cpu.h"
22*f798f1e2SMichael Clark #include "qemu/host-utils.h"
23*f798f1e2SMichael Clark #include "exec/exec-all.h"
24*f798f1e2SMichael Clark #include "exec/helper-proto.h"
25*f798f1e2SMichael Clark 
26*f798f1e2SMichael Clark target_ulong cpu_riscv_get_fflags(CPURISCVState *env)
27*f798f1e2SMichael Clark {
28*f798f1e2SMichael Clark     int soft = get_float_exception_flags(&env->fp_status);
29*f798f1e2SMichael Clark     target_ulong hard = 0;
30*f798f1e2SMichael Clark 
31*f798f1e2SMichael Clark     hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
32*f798f1e2SMichael Clark     hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
33*f798f1e2SMichael Clark     hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
34*f798f1e2SMichael Clark     hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
35*f798f1e2SMichael Clark     hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
36*f798f1e2SMichael Clark 
37*f798f1e2SMichael Clark     return hard;
38*f798f1e2SMichael Clark }
39*f798f1e2SMichael Clark 
40*f798f1e2SMichael Clark void cpu_riscv_set_fflags(CPURISCVState *env, target_ulong hard)
41*f798f1e2SMichael Clark {
42*f798f1e2SMichael Clark     int soft = 0;
43*f798f1e2SMichael Clark 
44*f798f1e2SMichael Clark     soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
45*f798f1e2SMichael Clark     soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
46*f798f1e2SMichael Clark     soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
47*f798f1e2SMichael Clark     soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
48*f798f1e2SMichael Clark     soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
49*f798f1e2SMichael Clark 
50*f798f1e2SMichael Clark     set_float_exception_flags(soft, &env->fp_status);
51*f798f1e2SMichael Clark }
52*f798f1e2SMichael Clark 
53*f798f1e2SMichael Clark void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
54*f798f1e2SMichael Clark {
55*f798f1e2SMichael Clark     int softrm;
56*f798f1e2SMichael Clark 
57*f798f1e2SMichael Clark     if (rm == 7) {
58*f798f1e2SMichael Clark         rm = env->frm;
59*f798f1e2SMichael Clark     }
60*f798f1e2SMichael Clark     switch (rm) {
61*f798f1e2SMichael Clark     case 0:
62*f798f1e2SMichael Clark         softrm = float_round_nearest_even;
63*f798f1e2SMichael Clark         break;
64*f798f1e2SMichael Clark     case 1:
65*f798f1e2SMichael Clark         softrm = float_round_to_zero;
66*f798f1e2SMichael Clark         break;
67*f798f1e2SMichael Clark     case 2:
68*f798f1e2SMichael Clark         softrm = float_round_down;
69*f798f1e2SMichael Clark         break;
70*f798f1e2SMichael Clark     case 3:
71*f798f1e2SMichael Clark         softrm = float_round_up;
72*f798f1e2SMichael Clark         break;
73*f798f1e2SMichael Clark     case 4:
74*f798f1e2SMichael Clark         softrm = float_round_ties_away;
75*f798f1e2SMichael Clark         break;
76*f798f1e2SMichael Clark     default:
77*f798f1e2SMichael Clark         do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
78*f798f1e2SMichael Clark     }
79*f798f1e2SMichael Clark 
80*f798f1e2SMichael Clark     set_float_rounding_mode(softrm, &env->fp_status);
81*f798f1e2SMichael Clark }
82*f798f1e2SMichael Clark 
83*f798f1e2SMichael Clark uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
84*f798f1e2SMichael Clark                         uint64_t frs3)
85*f798f1e2SMichael Clark {
86*f798f1e2SMichael Clark     return float32_muladd(frs1, frs2, frs3, 0, &env->fp_status);
87*f798f1e2SMichael Clark }
88*f798f1e2SMichael Clark 
89*f798f1e2SMichael Clark uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
90*f798f1e2SMichael Clark                         uint64_t frs3)
91*f798f1e2SMichael Clark {
92*f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
93*f798f1e2SMichael Clark }
94*f798f1e2SMichael Clark 
95*f798f1e2SMichael Clark uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
96*f798f1e2SMichael Clark                         uint64_t frs3)
97*f798f1e2SMichael Clark {
98*f798f1e2SMichael Clark     return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c,
99*f798f1e2SMichael Clark                           &env->fp_status);
100*f798f1e2SMichael Clark }
101*f798f1e2SMichael Clark 
102*f798f1e2SMichael Clark uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
103*f798f1e2SMichael Clark                         uint64_t frs3)
104*f798f1e2SMichael Clark {
105*f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c,
106*f798f1e2SMichael Clark                           &env->fp_status);
107*f798f1e2SMichael Clark }
108*f798f1e2SMichael Clark 
109*f798f1e2SMichael Clark uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
110*f798f1e2SMichael Clark                          uint64_t frs3)
111*f798f1e2SMichael Clark {
112*f798f1e2SMichael Clark     return float32_muladd(frs1, frs2, frs3, float_muladd_negate_product,
113*f798f1e2SMichael Clark                           &env->fp_status);
114*f798f1e2SMichael Clark }
115*f798f1e2SMichael Clark 
116*f798f1e2SMichael Clark uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
117*f798f1e2SMichael Clark                          uint64_t frs3)
118*f798f1e2SMichael Clark {
119*f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_product,
120*f798f1e2SMichael Clark                           &env->fp_status);
121*f798f1e2SMichael Clark }
122*f798f1e2SMichael Clark 
123*f798f1e2SMichael Clark uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
124*f798f1e2SMichael Clark                          uint64_t frs3)
125*f798f1e2SMichael Clark {
126*f798f1e2SMichael Clark     return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c |
127*f798f1e2SMichael Clark                           float_muladd_negate_product, &env->fp_status);
128*f798f1e2SMichael Clark }
129*f798f1e2SMichael Clark 
130*f798f1e2SMichael Clark uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
131*f798f1e2SMichael Clark                          uint64_t frs3)
132*f798f1e2SMichael Clark {
133*f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c |
134*f798f1e2SMichael Clark                           float_muladd_negate_product, &env->fp_status);
135*f798f1e2SMichael Clark }
136*f798f1e2SMichael Clark 
137*f798f1e2SMichael Clark uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
138*f798f1e2SMichael Clark {
139*f798f1e2SMichael Clark     return float32_add(frs1, frs2, &env->fp_status);
140*f798f1e2SMichael Clark }
141*f798f1e2SMichael Clark 
142*f798f1e2SMichael Clark uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
143*f798f1e2SMichael Clark {
144*f798f1e2SMichael Clark     return float32_sub(frs1, frs2, &env->fp_status);
145*f798f1e2SMichael Clark }
146*f798f1e2SMichael Clark 
147*f798f1e2SMichael Clark uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
148*f798f1e2SMichael Clark {
149*f798f1e2SMichael Clark     return float32_mul(frs1, frs2, &env->fp_status);
150*f798f1e2SMichael Clark }
151*f798f1e2SMichael Clark 
152*f798f1e2SMichael Clark uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
153*f798f1e2SMichael Clark {
154*f798f1e2SMichael Clark     return float32_div(frs1, frs2, &env->fp_status);
155*f798f1e2SMichael Clark }
156*f798f1e2SMichael Clark 
157*f798f1e2SMichael Clark uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
158*f798f1e2SMichael Clark {
159*f798f1e2SMichael Clark     return float32_minnum(frs1, frs2, &env->fp_status);
160*f798f1e2SMichael Clark }
161*f798f1e2SMichael Clark 
162*f798f1e2SMichael Clark uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
163*f798f1e2SMichael Clark {
164*f798f1e2SMichael Clark     return float32_maxnum(frs1, frs2, &env->fp_status);
165*f798f1e2SMichael Clark }
166*f798f1e2SMichael Clark 
167*f798f1e2SMichael Clark uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1)
168*f798f1e2SMichael Clark {
169*f798f1e2SMichael Clark     return float32_sqrt(frs1, &env->fp_status);
170*f798f1e2SMichael Clark }
171*f798f1e2SMichael Clark 
172*f798f1e2SMichael Clark target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
173*f798f1e2SMichael Clark {
174*f798f1e2SMichael Clark     return float32_le(frs1, frs2, &env->fp_status);
175*f798f1e2SMichael Clark }
176*f798f1e2SMichael Clark 
177*f798f1e2SMichael Clark target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
178*f798f1e2SMichael Clark {
179*f798f1e2SMichael Clark     return float32_lt(frs1, frs2, &env->fp_status);
180*f798f1e2SMichael Clark }
181*f798f1e2SMichael Clark 
182*f798f1e2SMichael Clark target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
183*f798f1e2SMichael Clark {
184*f798f1e2SMichael Clark     return float32_eq_quiet(frs1, frs2, &env->fp_status);
185*f798f1e2SMichael Clark }
186*f798f1e2SMichael Clark 
187*f798f1e2SMichael Clark target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1)
188*f798f1e2SMichael Clark {
189*f798f1e2SMichael Clark     return float32_to_int32(frs1, &env->fp_status);
190*f798f1e2SMichael Clark }
191*f798f1e2SMichael Clark 
192*f798f1e2SMichael Clark target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1)
193*f798f1e2SMichael Clark {
194*f798f1e2SMichael Clark     return (int32_t)float32_to_uint32(frs1, &env->fp_status);
195*f798f1e2SMichael Clark }
196*f798f1e2SMichael Clark 
197*f798f1e2SMichael Clark #if defined(TARGET_RISCV64)
198*f798f1e2SMichael Clark uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1)
199*f798f1e2SMichael Clark {
200*f798f1e2SMichael Clark     return float32_to_int64(frs1, &env->fp_status);
201*f798f1e2SMichael Clark }
202*f798f1e2SMichael Clark 
203*f798f1e2SMichael Clark uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1)
204*f798f1e2SMichael Clark {
205*f798f1e2SMichael Clark     return float32_to_uint64(frs1, &env->fp_status);
206*f798f1e2SMichael Clark }
207*f798f1e2SMichael Clark #endif
208*f798f1e2SMichael Clark 
209*f798f1e2SMichael Clark uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1)
210*f798f1e2SMichael Clark {
211*f798f1e2SMichael Clark     return int32_to_float32((int32_t)rs1, &env->fp_status);
212*f798f1e2SMichael Clark }
213*f798f1e2SMichael Clark 
214*f798f1e2SMichael Clark uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
215*f798f1e2SMichael Clark {
216*f798f1e2SMichael Clark     return uint32_to_float32((uint32_t)rs1, &env->fp_status);
217*f798f1e2SMichael Clark }
218*f798f1e2SMichael Clark 
219*f798f1e2SMichael Clark #if defined(TARGET_RISCV64)
220*f798f1e2SMichael Clark uint64_t helper_fcvt_s_l(CPURISCVState *env, uint64_t rs1)
221*f798f1e2SMichael Clark {
222*f798f1e2SMichael Clark     return int64_to_float32(rs1, &env->fp_status);
223*f798f1e2SMichael Clark }
224*f798f1e2SMichael Clark 
225*f798f1e2SMichael Clark uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)
226*f798f1e2SMichael Clark {
227*f798f1e2SMichael Clark     return uint64_to_float32(rs1, &env->fp_status);
228*f798f1e2SMichael Clark }
229*f798f1e2SMichael Clark #endif
230*f798f1e2SMichael Clark 
231*f798f1e2SMichael Clark target_ulong helper_fclass_s(uint64_t frs1)
232*f798f1e2SMichael Clark {
233*f798f1e2SMichael Clark     float32 f = frs1;
234*f798f1e2SMichael Clark     bool sign = float32_is_neg(f);
235*f798f1e2SMichael Clark 
236*f798f1e2SMichael Clark     if (float32_is_infinity(f)) {
237*f798f1e2SMichael Clark         return sign ? 1 << 0 : 1 << 7;
238*f798f1e2SMichael Clark     } else if (float32_is_zero(f)) {
239*f798f1e2SMichael Clark         return sign ? 1 << 3 : 1 << 4;
240*f798f1e2SMichael Clark     } else if (float32_is_zero_or_denormal(f)) {
241*f798f1e2SMichael Clark         return sign ? 1 << 2 : 1 << 5;
242*f798f1e2SMichael Clark     } else if (float32_is_any_nan(f)) {
243*f798f1e2SMichael Clark         float_status s = { }; /* for snan_bit_is_one */
244*f798f1e2SMichael Clark         return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
245*f798f1e2SMichael Clark     } else {
246*f798f1e2SMichael Clark         return sign ? 1 << 1 : 1 << 6;
247*f798f1e2SMichael Clark     }
248*f798f1e2SMichael Clark }
249*f798f1e2SMichael Clark 
250*f798f1e2SMichael Clark uint64_t helper_fadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
251*f798f1e2SMichael Clark {
252*f798f1e2SMichael Clark     return float64_add(frs1, frs2, &env->fp_status);
253*f798f1e2SMichael Clark }
254*f798f1e2SMichael Clark 
255*f798f1e2SMichael Clark uint64_t helper_fsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
256*f798f1e2SMichael Clark {
257*f798f1e2SMichael Clark     return float64_sub(frs1, frs2, &env->fp_status);
258*f798f1e2SMichael Clark }
259*f798f1e2SMichael Clark 
260*f798f1e2SMichael Clark uint64_t helper_fmul_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
261*f798f1e2SMichael Clark {
262*f798f1e2SMichael Clark     return float64_mul(frs1, frs2, &env->fp_status);
263*f798f1e2SMichael Clark }
264*f798f1e2SMichael Clark 
265*f798f1e2SMichael Clark uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
266*f798f1e2SMichael Clark {
267*f798f1e2SMichael Clark     return float64_div(frs1, frs2, &env->fp_status);
268*f798f1e2SMichael Clark }
269*f798f1e2SMichael Clark 
270*f798f1e2SMichael Clark uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
271*f798f1e2SMichael Clark {
272*f798f1e2SMichael Clark     return float64_minnum(frs1, frs2, &env->fp_status);
273*f798f1e2SMichael Clark }
274*f798f1e2SMichael Clark 
275*f798f1e2SMichael Clark uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
276*f798f1e2SMichael Clark {
277*f798f1e2SMichael Clark     return float64_maxnum(frs1, frs2, &env->fp_status);
278*f798f1e2SMichael Clark }
279*f798f1e2SMichael Clark 
280*f798f1e2SMichael Clark uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
281*f798f1e2SMichael Clark {
282*f798f1e2SMichael Clark     rs1 = float64_to_float32(rs1, &env->fp_status);
283*f798f1e2SMichael Clark     return float32_maybe_silence_nan(rs1, &env->fp_status);
284*f798f1e2SMichael Clark }
285*f798f1e2SMichael Clark 
286*f798f1e2SMichael Clark uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)
287*f798f1e2SMichael Clark {
288*f798f1e2SMichael Clark     rs1 = float32_to_float64(rs1, &env->fp_status);
289*f798f1e2SMichael Clark     return float64_maybe_silence_nan(rs1, &env->fp_status);
290*f798f1e2SMichael Clark }
291*f798f1e2SMichael Clark 
292*f798f1e2SMichael Clark uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)
293*f798f1e2SMichael Clark {
294*f798f1e2SMichael Clark     return float64_sqrt(frs1, &env->fp_status);
295*f798f1e2SMichael Clark }
296*f798f1e2SMichael Clark 
297*f798f1e2SMichael Clark target_ulong helper_fle_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
298*f798f1e2SMichael Clark {
299*f798f1e2SMichael Clark     return float64_le(frs1, frs2, &env->fp_status);
300*f798f1e2SMichael Clark }
301*f798f1e2SMichael Clark 
302*f798f1e2SMichael Clark target_ulong helper_flt_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
303*f798f1e2SMichael Clark {
304*f798f1e2SMichael Clark     return float64_lt(frs1, frs2, &env->fp_status);
305*f798f1e2SMichael Clark }
306*f798f1e2SMichael Clark 
307*f798f1e2SMichael Clark target_ulong helper_feq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
308*f798f1e2SMichael Clark {
309*f798f1e2SMichael Clark     return float64_eq_quiet(frs1, frs2, &env->fp_status);
310*f798f1e2SMichael Clark }
311*f798f1e2SMichael Clark 
312*f798f1e2SMichael Clark target_ulong helper_fcvt_w_d(CPURISCVState *env, uint64_t frs1)
313*f798f1e2SMichael Clark {
314*f798f1e2SMichael Clark     return float64_to_int32(frs1, &env->fp_status);
315*f798f1e2SMichael Clark }
316*f798f1e2SMichael Clark 
317*f798f1e2SMichael Clark target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
318*f798f1e2SMichael Clark {
319*f798f1e2SMichael Clark     return (int32_t)float64_to_uint32(frs1, &env->fp_status);
320*f798f1e2SMichael Clark }
321*f798f1e2SMichael Clark 
322*f798f1e2SMichael Clark #if defined(TARGET_RISCV64)
323*f798f1e2SMichael Clark uint64_t helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
324*f798f1e2SMichael Clark {
325*f798f1e2SMichael Clark     return float64_to_int64(frs1, &env->fp_status);
326*f798f1e2SMichael Clark }
327*f798f1e2SMichael Clark 
328*f798f1e2SMichael Clark uint64_t helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
329*f798f1e2SMichael Clark {
330*f798f1e2SMichael Clark     return float64_to_uint64(frs1, &env->fp_status);
331*f798f1e2SMichael Clark }
332*f798f1e2SMichael Clark #endif
333*f798f1e2SMichael Clark 
334*f798f1e2SMichael Clark uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1)
335*f798f1e2SMichael Clark {
336*f798f1e2SMichael Clark     return int32_to_float64((int32_t)rs1, &env->fp_status);
337*f798f1e2SMichael Clark }
338*f798f1e2SMichael Clark 
339*f798f1e2SMichael Clark uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
340*f798f1e2SMichael Clark {
341*f798f1e2SMichael Clark     return uint32_to_float64((uint32_t)rs1, &env->fp_status);
342*f798f1e2SMichael Clark }
343*f798f1e2SMichael Clark 
344*f798f1e2SMichael Clark #if defined(TARGET_RISCV64)
345*f798f1e2SMichael Clark uint64_t helper_fcvt_d_l(CPURISCVState *env, uint64_t rs1)
346*f798f1e2SMichael Clark {
347*f798f1e2SMichael Clark     return int64_to_float64(rs1, &env->fp_status);
348*f798f1e2SMichael Clark }
349*f798f1e2SMichael Clark 
350*f798f1e2SMichael Clark uint64_t helper_fcvt_d_lu(CPURISCVState *env, uint64_t rs1)
351*f798f1e2SMichael Clark {
352*f798f1e2SMichael Clark     return uint64_to_float64(rs1, &env->fp_status);
353*f798f1e2SMichael Clark }
354*f798f1e2SMichael Clark #endif
355*f798f1e2SMichael Clark 
356*f798f1e2SMichael Clark target_ulong helper_fclass_d(uint64_t frs1)
357*f798f1e2SMichael Clark {
358*f798f1e2SMichael Clark     float64 f = frs1;
359*f798f1e2SMichael Clark     bool sign = float64_is_neg(f);
360*f798f1e2SMichael Clark 
361*f798f1e2SMichael Clark     if (float64_is_infinity(f)) {
362*f798f1e2SMichael Clark         return sign ? 1 << 0 : 1 << 7;
363*f798f1e2SMichael Clark     } else if (float64_is_zero(f)) {
364*f798f1e2SMichael Clark         return sign ? 1 << 3 : 1 << 4;
365*f798f1e2SMichael Clark     } else if (float64_is_zero_or_denormal(f)) {
366*f798f1e2SMichael Clark         return sign ? 1 << 2 : 1 << 5;
367*f798f1e2SMichael Clark     } else if (float64_is_any_nan(f)) {
368*f798f1e2SMichael Clark         float_status s = { }; /* for snan_bit_is_one */
369*f798f1e2SMichael Clark         return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8;
370*f798f1e2SMichael Clark     } else {
371*f798f1e2SMichael Clark         return sign ? 1 << 1 : 1 << 6;
372*f798f1e2SMichael Clark     }
373*f798f1e2SMichael Clark }
374