xref: /qemu/target/riscv/fpu_helper.c (revision 11f9c450a6772c095c5f9c40f5a08c2f8d15a9a1)
1f798f1e2SMichael Clark /*
2f798f1e2SMichael Clark  * RISC-V FPU Emulation Helpers for QEMU.
3f798f1e2SMichael Clark  *
4f798f1e2SMichael Clark  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5f798f1e2SMichael Clark  *
6f798f1e2SMichael Clark  * This program is free software; you can redistribute it and/or modify it
7f798f1e2SMichael Clark  * under the terms and conditions of the GNU General Public License,
8f798f1e2SMichael Clark  * version 2 or later, as published by the Free Software Foundation.
9f798f1e2SMichael Clark  *
10f798f1e2SMichael Clark  * This program is distributed in the hope it will be useful, but WITHOUT
11f798f1e2SMichael Clark  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12f798f1e2SMichael Clark  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13f798f1e2SMichael Clark  * more details.
14f798f1e2SMichael Clark  *
15f798f1e2SMichael Clark  * You should have received a copy of the GNU General Public License along with
16f798f1e2SMichael Clark  * this program.  If not, see <http://www.gnu.org/licenses/>.
17f798f1e2SMichael Clark  */
18f798f1e2SMichael Clark 
19f798f1e2SMichael Clark #include "qemu/osdep.h"
20f798f1e2SMichael Clark #include "cpu.h"
21f798f1e2SMichael Clark #include "qemu/host-utils.h"
22f798f1e2SMichael Clark #include "exec/exec-all.h"
23f798f1e2SMichael Clark #include "exec/helper-proto.h"
24135b03cbSAlex Bennée #include "fpu/softfloat.h"
25121ddbb3SLIU Zhiwei #include "internals.h"
26f798f1e2SMichael Clark 
27fb738839SMichael Clark target_ulong riscv_cpu_get_fflags(CPURISCVState *env)
28f798f1e2SMichael Clark {
29f798f1e2SMichael Clark     int soft = get_float_exception_flags(&env->fp_status);
30f798f1e2SMichael Clark     target_ulong hard = 0;
31f798f1e2SMichael Clark 
32f798f1e2SMichael Clark     hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0;
33f798f1e2SMichael Clark     hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0;
34f798f1e2SMichael Clark     hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0;
35f798f1e2SMichael Clark     hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0;
36f798f1e2SMichael Clark     hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0;
37f798f1e2SMichael Clark 
38f798f1e2SMichael Clark     return hard;
39f798f1e2SMichael Clark }
40f798f1e2SMichael Clark 
41fb738839SMichael Clark void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard)
42f798f1e2SMichael Clark {
43f798f1e2SMichael Clark     int soft = 0;
44f798f1e2SMichael Clark 
45f798f1e2SMichael Clark     soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0;
46f798f1e2SMichael Clark     soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0;
47f798f1e2SMichael Clark     soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0;
48f798f1e2SMichael Clark     soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0;
49f798f1e2SMichael Clark     soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0;
50f798f1e2SMichael Clark 
51f798f1e2SMichael Clark     set_float_exception_flags(soft, &env->fp_status);
52f798f1e2SMichael Clark }
53f798f1e2SMichael Clark 
54f798f1e2SMichael Clark void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
55f798f1e2SMichael Clark {
56f798f1e2SMichael Clark     int softrm;
57f798f1e2SMichael Clark 
58f798f1e2SMichael Clark     if (rm == 7) {
59f798f1e2SMichael Clark         rm = env->frm;
60f798f1e2SMichael Clark     }
61f798f1e2SMichael Clark     switch (rm) {
62f798f1e2SMichael Clark     case 0:
63f798f1e2SMichael Clark         softrm = float_round_nearest_even;
64f798f1e2SMichael Clark         break;
65f798f1e2SMichael Clark     case 1:
66f798f1e2SMichael Clark         softrm = float_round_to_zero;
67f798f1e2SMichael Clark         break;
68f798f1e2SMichael Clark     case 2:
69f798f1e2SMichael Clark         softrm = float_round_down;
70f798f1e2SMichael Clark         break;
71f798f1e2SMichael Clark     case 3:
72f798f1e2SMichael Clark         softrm = float_round_up;
73f798f1e2SMichael Clark         break;
74f798f1e2SMichael Clark     case 4:
75f798f1e2SMichael Clark         softrm = float_round_ties_away;
76f798f1e2SMichael Clark         break;
77f798f1e2SMichael Clark     default:
78fb738839SMichael Clark         riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
79f798f1e2SMichael Clark     }
80f798f1e2SMichael Clark 
81f798f1e2SMichael Clark     set_float_rounding_mode(softrm, &env->fp_status);
82f798f1e2SMichael Clark }
83f798f1e2SMichael Clark 
8400c1899fSKito Cheng static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
8500c1899fSKito Cheng                            uint64_t rs3, int flags)
8600c1899fSKito Cheng {
8700c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
8800c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
8900c1899fSKito Cheng     float16 frs3 = check_nanbox_h(rs3);
9000c1899fSKito Cheng     return nanbox_h(float16_muladd(frs1, frs2, frs3, flags, &env->fp_status));
9100c1899fSKito Cheng }
9200c1899fSKito Cheng 
9300e925c5SRichard Henderson static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
9400e925c5SRichard Henderson                            uint64_t rs3, int flags)
959921e3d3SRichard Henderson {
9600e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
9700e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
9800e925c5SRichard Henderson     float32 frs3 = check_nanbox_s(rs3);
999921e3d3SRichard Henderson     return nanbox_s(float32_muladd(frs1, frs2, frs3, flags, &env->fp_status));
1009921e3d3SRichard Henderson }
1019921e3d3SRichard Henderson 
102f798f1e2SMichael Clark uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
103f798f1e2SMichael Clark                         uint64_t frs3)
104f798f1e2SMichael Clark {
1059921e3d3SRichard Henderson     return do_fmadd_s(env, frs1, frs2, frs3, 0);
106f798f1e2SMichael Clark }
107f798f1e2SMichael Clark 
108f798f1e2SMichael Clark uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
109f798f1e2SMichael Clark                         uint64_t frs3)
110f798f1e2SMichael Clark {
111f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
112f798f1e2SMichael Clark }
113f798f1e2SMichael Clark 
11400c1899fSKito Cheng uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
11500c1899fSKito Cheng                         uint64_t frs3)
11600c1899fSKito Cheng {
11700c1899fSKito Cheng     return do_fmadd_h(env, frs1, frs2, frs3, 0);
11800c1899fSKito Cheng }
11900c1899fSKito Cheng 
120f798f1e2SMichael Clark uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
121f798f1e2SMichael Clark                         uint64_t frs3)
122f798f1e2SMichael Clark {
1239921e3d3SRichard Henderson     return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_c);
124f798f1e2SMichael Clark }
125f798f1e2SMichael Clark 
126f798f1e2SMichael Clark uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
127f798f1e2SMichael Clark                         uint64_t frs3)
128f798f1e2SMichael Clark {
129f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c,
130f798f1e2SMichael Clark                           &env->fp_status);
131f798f1e2SMichael Clark }
132f798f1e2SMichael Clark 
13300c1899fSKito Cheng uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
13400c1899fSKito Cheng                         uint64_t frs3)
13500c1899fSKito Cheng {
13600c1899fSKito Cheng     return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c);
13700c1899fSKito Cheng }
13800c1899fSKito Cheng 
139f798f1e2SMichael Clark uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
140f798f1e2SMichael Clark                          uint64_t frs3)
141f798f1e2SMichael Clark {
1429921e3d3SRichard Henderson     return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_product);
143f798f1e2SMichael Clark }
144f798f1e2SMichael Clark 
145f798f1e2SMichael Clark uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
146f798f1e2SMichael Clark                          uint64_t frs3)
147f798f1e2SMichael Clark {
148f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_product,
149f798f1e2SMichael Clark                           &env->fp_status);
150f798f1e2SMichael Clark }
151f798f1e2SMichael Clark 
15200c1899fSKito Cheng uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
15300c1899fSKito Cheng                          uint64_t frs3)
15400c1899fSKito Cheng {
15500c1899fSKito Cheng     return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product);
15600c1899fSKito Cheng }
15700c1899fSKito Cheng 
158f798f1e2SMichael Clark uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
159f798f1e2SMichael Clark                          uint64_t frs3)
160f798f1e2SMichael Clark {
1619921e3d3SRichard Henderson     return do_fmadd_s(env, frs1, frs2, frs3,
1629921e3d3SRichard Henderson                       float_muladd_negate_c | float_muladd_negate_product);
163f798f1e2SMichael Clark }
164f798f1e2SMichael Clark 
165f798f1e2SMichael Clark uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
166f798f1e2SMichael Clark                          uint64_t frs3)
167f798f1e2SMichael Clark {
168f798f1e2SMichael Clark     return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c |
169f798f1e2SMichael Clark                           float_muladd_negate_product, &env->fp_status);
170f798f1e2SMichael Clark }
171f798f1e2SMichael Clark 
17200c1899fSKito Cheng uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
17300c1899fSKito Cheng                          uint64_t frs3)
17400c1899fSKito Cheng {
17500c1899fSKito Cheng     return do_fmadd_h(env, frs1, frs2, frs3,
17600c1899fSKito Cheng                       float_muladd_negate_c | float_muladd_negate_product);
17700c1899fSKito Cheng }
17800c1899fSKito Cheng 
17900e925c5SRichard Henderson uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
180f798f1e2SMichael Clark {
18100e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
18200e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
1839921e3d3SRichard Henderson     return nanbox_s(float32_add(frs1, frs2, &env->fp_status));
184f798f1e2SMichael Clark }
185f798f1e2SMichael Clark 
18600e925c5SRichard Henderson uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
187f798f1e2SMichael Clark {
18800e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
18900e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
1909921e3d3SRichard Henderson     return nanbox_s(float32_sub(frs1, frs2, &env->fp_status));
191f798f1e2SMichael Clark }
192f798f1e2SMichael Clark 
19300e925c5SRichard Henderson uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
194f798f1e2SMichael Clark {
19500e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
19600e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
1979921e3d3SRichard Henderson     return nanbox_s(float32_mul(frs1, frs2, &env->fp_status));
198f798f1e2SMichael Clark }
199f798f1e2SMichael Clark 
20000e925c5SRichard Henderson uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
201f798f1e2SMichael Clark {
20200e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
20300e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
2049921e3d3SRichard Henderson     return nanbox_s(float32_div(frs1, frs2, &env->fp_status));
205f798f1e2SMichael Clark }
206f798f1e2SMichael Clark 
20700e925c5SRichard Henderson uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
208f798f1e2SMichael Clark {
20900e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
21000e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
21115161e42SChih-Min Chao     return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
21215161e42SChih-Min Chao                     float32_minnum(frs1, frs2, &env->fp_status) :
21315161e42SChih-Min Chao                     float32_minimum_number(frs1, frs2, &env->fp_status));
214f798f1e2SMichael Clark }
215f798f1e2SMichael Clark 
21600e925c5SRichard Henderson uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
217f798f1e2SMichael Clark {
21800e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
21900e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
22015161e42SChih-Min Chao     return nanbox_s(env->priv_ver < PRIV_VERSION_1_11_0 ?
22115161e42SChih-Min Chao                     float32_maxnum(frs1, frs2, &env->fp_status) :
22215161e42SChih-Min Chao                     float32_maximum_number(frs1, frs2, &env->fp_status));
223f798f1e2SMichael Clark }
224f798f1e2SMichael Clark 
22500e925c5SRichard Henderson uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
226f798f1e2SMichael Clark {
22700e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
2289921e3d3SRichard Henderson     return nanbox_s(float32_sqrt(frs1, &env->fp_status));
229f798f1e2SMichael Clark }
230f798f1e2SMichael Clark 
23100e925c5SRichard Henderson target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
232f798f1e2SMichael Clark {
23300e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
23400e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
235f798f1e2SMichael Clark     return float32_le(frs1, frs2, &env->fp_status);
236f798f1e2SMichael Clark }
237f798f1e2SMichael Clark 
23800e925c5SRichard Henderson target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
239f798f1e2SMichael Clark {
24000e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
24100e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
242f798f1e2SMichael Clark     return float32_lt(frs1, frs2, &env->fp_status);
243f798f1e2SMichael Clark }
244f798f1e2SMichael Clark 
24500e925c5SRichard Henderson target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
246f798f1e2SMichael Clark {
24700e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
24800e925c5SRichard Henderson     float32 frs2 = check_nanbox_s(rs2);
249f798f1e2SMichael Clark     return float32_eq_quiet(frs1, frs2, &env->fp_status);
250f798f1e2SMichael Clark }
251f798f1e2SMichael Clark 
25200e925c5SRichard Henderson target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1)
253f798f1e2SMichael Clark {
25400e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
255f798f1e2SMichael Clark     return float32_to_int32(frs1, &env->fp_status);
256f798f1e2SMichael Clark }
257f798f1e2SMichael Clark 
25800e925c5SRichard Henderson target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
259f798f1e2SMichael Clark {
26000e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
261f798f1e2SMichael Clark     return (int32_t)float32_to_uint32(frs1, &env->fp_status);
262f798f1e2SMichael Clark }
263f798f1e2SMichael Clark 
264daf866b6SAlistair Francis target_ulong helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
265f798f1e2SMichael Clark {
26600e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
267f798f1e2SMichael Clark     return float32_to_int64(frs1, &env->fp_status);
268f798f1e2SMichael Clark }
269f798f1e2SMichael Clark 
270daf866b6SAlistair Francis target_ulong helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
271f798f1e2SMichael Clark {
27200e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
273f798f1e2SMichael Clark     return float32_to_uint64(frs1, &env->fp_status);
274f798f1e2SMichael Clark }
275f798f1e2SMichael Clark 
276f798f1e2SMichael Clark uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1)
277f798f1e2SMichael Clark {
2789921e3d3SRichard Henderson     return nanbox_s(int32_to_float32((int32_t)rs1, &env->fp_status));
279f798f1e2SMichael Clark }
280f798f1e2SMichael Clark 
281f798f1e2SMichael Clark uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
282f798f1e2SMichael Clark {
2839921e3d3SRichard Henderson     return nanbox_s(uint32_to_float32((uint32_t)rs1, &env->fp_status));
284f798f1e2SMichael Clark }
285f798f1e2SMichael Clark 
286daf866b6SAlistair Francis uint64_t helper_fcvt_s_l(CPURISCVState *env, target_ulong rs1)
287f798f1e2SMichael Clark {
2889921e3d3SRichard Henderson     return nanbox_s(int64_to_float32(rs1, &env->fp_status));
289f798f1e2SMichael Clark }
290f798f1e2SMichael Clark 
291daf866b6SAlistair Francis uint64_t helper_fcvt_s_lu(CPURISCVState *env, target_ulong rs1)
292f798f1e2SMichael Clark {
2939921e3d3SRichard Henderson     return nanbox_s(uint64_to_float32(rs1, &env->fp_status));
294f798f1e2SMichael Clark }
295f798f1e2SMichael Clark 
29600e925c5SRichard Henderson target_ulong helper_fclass_s(uint64_t rs1)
297f798f1e2SMichael Clark {
29800e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
299121ddbb3SLIU Zhiwei     return fclass_s(frs1);
300f798f1e2SMichael Clark }
301f798f1e2SMichael Clark 
302f798f1e2SMichael Clark uint64_t helper_fadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
303f798f1e2SMichael Clark {
304f798f1e2SMichael Clark     return float64_add(frs1, frs2, &env->fp_status);
305f798f1e2SMichael Clark }
306f798f1e2SMichael Clark 
307f798f1e2SMichael Clark uint64_t helper_fsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
308f798f1e2SMichael Clark {
309f798f1e2SMichael Clark     return float64_sub(frs1, frs2, &env->fp_status);
310f798f1e2SMichael Clark }
311f798f1e2SMichael Clark 
312f798f1e2SMichael Clark uint64_t helper_fmul_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
313f798f1e2SMichael Clark {
314f798f1e2SMichael Clark     return float64_mul(frs1, frs2, &env->fp_status);
315f798f1e2SMichael Clark }
316f798f1e2SMichael Clark 
317f798f1e2SMichael Clark uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
318f798f1e2SMichael Clark {
319f798f1e2SMichael Clark     return float64_div(frs1, frs2, &env->fp_status);
320f798f1e2SMichael Clark }
321f798f1e2SMichael Clark 
322f798f1e2SMichael Clark uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
323f798f1e2SMichael Clark {
32415161e42SChih-Min Chao     return env->priv_ver < PRIV_VERSION_1_11_0 ?
32515161e42SChih-Min Chao             float64_minnum(frs1, frs2, &env->fp_status) :
32615161e42SChih-Min Chao             float64_minimum_number(frs1, frs2, &env->fp_status);
327f798f1e2SMichael Clark }
328f798f1e2SMichael Clark 
329f798f1e2SMichael Clark uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
330f798f1e2SMichael Clark {
33115161e42SChih-Min Chao     return env->priv_ver < PRIV_VERSION_1_11_0 ?
33215161e42SChih-Min Chao             float64_maxnum(frs1, frs2, &env->fp_status) :
33315161e42SChih-Min Chao             float64_maximum_number(frs1, frs2, &env->fp_status);
334f798f1e2SMichael Clark }
335f798f1e2SMichael Clark 
336f798f1e2SMichael Clark uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
337f798f1e2SMichael Clark {
3389921e3d3SRichard Henderson     return nanbox_s(float64_to_float32(rs1, &env->fp_status));
339f798f1e2SMichael Clark }
340f798f1e2SMichael Clark 
341f798f1e2SMichael Clark uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)
342f798f1e2SMichael Clark {
34300e925c5SRichard Henderson     float32 frs1 = check_nanbox_s(rs1);
34400e925c5SRichard Henderson     return float32_to_float64(frs1, &env->fp_status);
345f798f1e2SMichael Clark }
346f798f1e2SMichael Clark 
347f798f1e2SMichael Clark uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)
348f798f1e2SMichael Clark {
349f798f1e2SMichael Clark     return float64_sqrt(frs1, &env->fp_status);
350f798f1e2SMichael Clark }
351f798f1e2SMichael Clark 
352f798f1e2SMichael Clark target_ulong helper_fle_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
353f798f1e2SMichael Clark {
354f798f1e2SMichael Clark     return float64_le(frs1, frs2, &env->fp_status);
355f798f1e2SMichael Clark }
356f798f1e2SMichael Clark 
357f798f1e2SMichael Clark target_ulong helper_flt_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
358f798f1e2SMichael Clark {
359f798f1e2SMichael Clark     return float64_lt(frs1, frs2, &env->fp_status);
360f798f1e2SMichael Clark }
361f798f1e2SMichael Clark 
362f798f1e2SMichael Clark target_ulong helper_feq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
363f798f1e2SMichael Clark {
364f798f1e2SMichael Clark     return float64_eq_quiet(frs1, frs2, &env->fp_status);
365f798f1e2SMichael Clark }
366f798f1e2SMichael Clark 
367f798f1e2SMichael Clark target_ulong helper_fcvt_w_d(CPURISCVState *env, uint64_t frs1)
368f798f1e2SMichael Clark {
369f798f1e2SMichael Clark     return float64_to_int32(frs1, &env->fp_status);
370f798f1e2SMichael Clark }
371f798f1e2SMichael Clark 
372f798f1e2SMichael Clark target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
373f798f1e2SMichael Clark {
374f798f1e2SMichael Clark     return (int32_t)float64_to_uint32(frs1, &env->fp_status);
375f798f1e2SMichael Clark }
376f798f1e2SMichael Clark 
377daf866b6SAlistair Francis target_ulong helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
378f798f1e2SMichael Clark {
379f798f1e2SMichael Clark     return float64_to_int64(frs1, &env->fp_status);
380f798f1e2SMichael Clark }
381f798f1e2SMichael Clark 
382daf866b6SAlistair Francis target_ulong helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
383f798f1e2SMichael Clark {
384f798f1e2SMichael Clark     return float64_to_uint64(frs1, &env->fp_status);
385f798f1e2SMichael Clark }
386f798f1e2SMichael Clark 
387f798f1e2SMichael Clark uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1)
388f798f1e2SMichael Clark {
389f798f1e2SMichael Clark     return int32_to_float64((int32_t)rs1, &env->fp_status);
390f798f1e2SMichael Clark }
391f798f1e2SMichael Clark 
392f798f1e2SMichael Clark uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
393f798f1e2SMichael Clark {
394f798f1e2SMichael Clark     return uint32_to_float64((uint32_t)rs1, &env->fp_status);
395f798f1e2SMichael Clark }
396f798f1e2SMichael Clark 
397daf866b6SAlistair Francis uint64_t helper_fcvt_d_l(CPURISCVState *env, target_ulong rs1)
398f798f1e2SMichael Clark {
399f798f1e2SMichael Clark     return int64_to_float64(rs1, &env->fp_status);
400f798f1e2SMichael Clark }
401f798f1e2SMichael Clark 
402daf866b6SAlistair Francis uint64_t helper_fcvt_d_lu(CPURISCVState *env, target_ulong rs1)
403f798f1e2SMichael Clark {
404f798f1e2SMichael Clark     return uint64_to_float64(rs1, &env->fp_status);
405f798f1e2SMichael Clark }
406f798f1e2SMichael Clark 
407f798f1e2SMichael Clark target_ulong helper_fclass_d(uint64_t frs1)
408f798f1e2SMichael Clark {
409121ddbb3SLIU Zhiwei     return fclass_d(frs1);
410f798f1e2SMichael Clark }
41100c1899fSKito Cheng 
41200c1899fSKito Cheng uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
41300c1899fSKito Cheng {
41400c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
41500c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
41600c1899fSKito Cheng     return nanbox_h(float16_add(frs1, frs2, &env->fp_status));
41700c1899fSKito Cheng }
41800c1899fSKito Cheng 
41900c1899fSKito Cheng uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
42000c1899fSKito Cheng {
42100c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
42200c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
42300c1899fSKito Cheng     return nanbox_h(float16_sub(frs1, frs2, &env->fp_status));
42400c1899fSKito Cheng }
42500c1899fSKito Cheng 
42600c1899fSKito Cheng uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
42700c1899fSKito Cheng {
42800c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
42900c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
43000c1899fSKito Cheng     return nanbox_h(float16_mul(frs1, frs2, &env->fp_status));
43100c1899fSKito Cheng }
43200c1899fSKito Cheng 
43300c1899fSKito Cheng uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
43400c1899fSKito Cheng {
43500c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
43600c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
43700c1899fSKito Cheng     return nanbox_h(float16_div(frs1, frs2, &env->fp_status));
43800c1899fSKito Cheng }
43900c1899fSKito Cheng 
44000c1899fSKito Cheng uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
44100c1899fSKito Cheng {
44200c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
44300c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
44400c1899fSKito Cheng     return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ?
44500c1899fSKito Cheng                     float16_minnum(frs1, frs2, &env->fp_status) :
44600c1899fSKito Cheng                     float16_minimum_number(frs1, frs2, &env->fp_status));
44700c1899fSKito Cheng }
44800c1899fSKito Cheng 
44900c1899fSKito Cheng uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
45000c1899fSKito Cheng {
45100c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
45200c1899fSKito Cheng     float16 frs2 = check_nanbox_h(rs2);
45300c1899fSKito Cheng     return nanbox_h(env->priv_ver < PRIV_VERSION_1_11_0 ?
45400c1899fSKito Cheng                     float16_maxnum(frs1, frs2, &env->fp_status) :
45500c1899fSKito Cheng                     float16_maximum_number(frs1, frs2, &env->fp_status));
45600c1899fSKito Cheng }
45700c1899fSKito Cheng 
45800c1899fSKito Cheng uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
45900c1899fSKito Cheng {
46000c1899fSKito Cheng     float16 frs1 = check_nanbox_h(rs1);
46100c1899fSKito Cheng     return nanbox_h(float16_sqrt(frs1, &env->fp_status));
46200c1899fSKito Cheng }
4637b03c8e5SKito Cheng 
464*11f9c450SKito Cheng target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
465*11f9c450SKito Cheng {
466*11f9c450SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
467*11f9c450SKito Cheng     float16 frs2 = check_nanbox_h(rs2);
468*11f9c450SKito Cheng     return float16_le(frs1, frs2, &env->fp_status);
469*11f9c450SKito Cheng }
470*11f9c450SKito Cheng 
471*11f9c450SKito Cheng target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
472*11f9c450SKito Cheng {
473*11f9c450SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
474*11f9c450SKito Cheng     float16 frs2 = check_nanbox_h(rs2);
475*11f9c450SKito Cheng     return float16_lt(frs1, frs2, &env->fp_status);
476*11f9c450SKito Cheng }
477*11f9c450SKito Cheng 
478*11f9c450SKito Cheng target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
479*11f9c450SKito Cheng {
480*11f9c450SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
481*11f9c450SKito Cheng     float16 frs2 = check_nanbox_h(rs2);
482*11f9c450SKito Cheng     return float16_eq_quiet(frs1, frs2, &env->fp_status);
483*11f9c450SKito Cheng }
484*11f9c450SKito Cheng 
4857b03c8e5SKito Cheng target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
4867b03c8e5SKito Cheng {
4877b03c8e5SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
4887b03c8e5SKito Cheng     return float16_to_int32(frs1, &env->fp_status);
4897b03c8e5SKito Cheng }
4907b03c8e5SKito Cheng 
4917b03c8e5SKito Cheng target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1)
4927b03c8e5SKito Cheng {
4937b03c8e5SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
4947b03c8e5SKito Cheng     return (int32_t)float16_to_uint32(frs1, &env->fp_status);
4957b03c8e5SKito Cheng }
4967b03c8e5SKito Cheng 
4977b03c8e5SKito Cheng target_ulong helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1)
4987b03c8e5SKito Cheng {
4997b03c8e5SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
5007b03c8e5SKito Cheng     return float16_to_int64(frs1, &env->fp_status);
5017b03c8e5SKito Cheng }
5027b03c8e5SKito Cheng 
5037b03c8e5SKito Cheng target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1)
5047b03c8e5SKito Cheng {
5057b03c8e5SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
5067b03c8e5SKito Cheng     return float16_to_uint64(frs1, &env->fp_status);
5077b03c8e5SKito Cheng }
5087b03c8e5SKito Cheng 
5097b03c8e5SKito Cheng uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1)
5107b03c8e5SKito Cheng {
5117b03c8e5SKito Cheng     return nanbox_h(int32_to_float16((int32_t)rs1, &env->fp_status));
5127b03c8e5SKito Cheng }
5137b03c8e5SKito Cheng 
5147b03c8e5SKito Cheng uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1)
5157b03c8e5SKito Cheng {
5167b03c8e5SKito Cheng     return nanbox_h(uint32_to_float16((uint32_t)rs1, &env->fp_status));
5177b03c8e5SKito Cheng }
5187b03c8e5SKito Cheng 
5197b03c8e5SKito Cheng uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1)
5207b03c8e5SKito Cheng {
5217b03c8e5SKito Cheng     return nanbox_h(int64_to_float16(rs1, &env->fp_status));
5227b03c8e5SKito Cheng }
5237b03c8e5SKito Cheng 
5247b03c8e5SKito Cheng uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1)
5257b03c8e5SKito Cheng {
5267b03c8e5SKito Cheng     return nanbox_h(uint64_to_float16(rs1, &env->fp_status));
5277b03c8e5SKito Cheng }
5287b03c8e5SKito Cheng 
5297b03c8e5SKito Cheng uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1)
5307b03c8e5SKito Cheng {
5317b03c8e5SKito Cheng     float32 frs1 = check_nanbox_s(rs1);
5327b03c8e5SKito Cheng     return nanbox_h(float32_to_float16(frs1, true, &env->fp_status));
5337b03c8e5SKito Cheng }
5347b03c8e5SKito Cheng 
5357b03c8e5SKito Cheng uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1)
5367b03c8e5SKito Cheng {
5377b03c8e5SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
5387b03c8e5SKito Cheng     return nanbox_s(float16_to_float32(frs1, true, &env->fp_status));
5397b03c8e5SKito Cheng }
5407b03c8e5SKito Cheng 
5417b03c8e5SKito Cheng uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1)
5427b03c8e5SKito Cheng {
5437b03c8e5SKito Cheng     return nanbox_h(float64_to_float16(rs1, true, &env->fp_status));
5447b03c8e5SKito Cheng }
5457b03c8e5SKito Cheng 
5467b03c8e5SKito Cheng uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
5477b03c8e5SKito Cheng {
5487b03c8e5SKito Cheng     float16 frs1 = check_nanbox_h(rs1);
5497b03c8e5SKito Cheng     return float16_to_float64(frs1, true, &env->fp_status);
5507b03c8e5SKito Cheng }
551