]>
Commit | Line | Data |
---|---|---|
f798f1e2 MC |
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" | |
f798f1e2 MC |
20 | #include "cpu.h" |
21 | #include "qemu/host-utils.h" | |
22 | #include "exec/exec-all.h" | |
23 | #include "exec/helper-proto.h" | |
135b03cb | 24 | #include "fpu/softfloat.h" |
121ddbb3 | 25 | #include "internals.h" |
f798f1e2 | 26 | |
fb738839 | 27 | target_ulong riscv_cpu_get_fflags(CPURISCVState *env) |
f798f1e2 MC |
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 | ||
fb738839 | 41 | void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong hard) |
f798f1e2 MC |
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 | ||
986c895d | 58 | if (rm == RISCV_FRM_DYN) { |
f798f1e2 MC |
59 | rm = env->frm; |
60 | } | |
61 | switch (rm) { | |
986c895d | 62 | case RISCV_FRM_RNE: |
f798f1e2 MC |
63 | softrm = float_round_nearest_even; |
64 | break; | |
986c895d | 65 | case RISCV_FRM_RTZ: |
f798f1e2 MC |
66 | softrm = float_round_to_zero; |
67 | break; | |
986c895d | 68 | case RISCV_FRM_RDN: |
f798f1e2 MC |
69 | softrm = float_round_down; |
70 | break; | |
986c895d | 71 | case RISCV_FRM_RUP: |
f798f1e2 MC |
72 | softrm = float_round_up; |
73 | break; | |
986c895d | 74 | case RISCV_FRM_RMM: |
f798f1e2 MC |
75 | softrm = float_round_ties_away; |
76 | break; | |
77 | default: | |
fb738839 | 78 | riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); |
f798f1e2 MC |
79 | } |
80 | ||
81 | set_float_rounding_mode(softrm, &env->fp_status); | |
82 | } | |
83 | ||
3ceeb19a RH |
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 | ||
00c1899f KC |
121 | static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2, |
122 | uint64_t rs3, int flags) | |
123 | { | |
a2464a4c WL |
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)); | |
00c1899f KC |
129 | } |
130 | ||
00e925c5 RH |
131 | static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2, |
132 | uint64_t rs3, int flags) | |
9921e3d3 | 133 | { |
e1a29bbd WL |
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)); | |
9921e3d3 RH |
139 | } |
140 | ||
f798f1e2 MC |
141 | uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, |
142 | uint64_t frs3) | |
143 | { | |
9921e3d3 | 144 | return do_fmadd_s(env, frs1, frs2, frs3, 0); |
f798f1e2 MC |
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 | ||
00c1899f KC |
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 | ||
f798f1e2 MC |
159 | uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, |
160 | uint64_t frs3) | |
161 | { | |
9921e3d3 | 162 | return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_c); |
f798f1e2 MC |
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 | ||
00c1899f KC |
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 | ||
f798f1e2 MC |
178 | uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, |
179 | uint64_t frs3) | |
180 | { | |
9921e3d3 | 181 | return do_fmadd_s(env, frs1, frs2, frs3, float_muladd_negate_product); |
f798f1e2 MC |
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 | ||
00c1899f KC |
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 | ||
f798f1e2 MC |
197 | uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, |
198 | uint64_t frs3) | |
199 | { | |
9921e3d3 RH |
200 | return do_fmadd_s(env, frs1, frs2, frs3, |
201 | float_muladd_negate_c | float_muladd_negate_product); | |
f798f1e2 MC |
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 | ||
00c1899f KC |
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 | ||
00e925c5 | 218 | uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 219 | { |
e1a29bbd WL |
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)); | |
f798f1e2 MC |
223 | } |
224 | ||
00e925c5 | 225 | uint64_t helper_fsub_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 226 | { |
e1a29bbd WL |
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)); | |
f798f1e2 MC |
230 | } |
231 | ||
00e925c5 | 232 | uint64_t helper_fmul_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 233 | { |
e1a29bbd WL |
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)); | |
f798f1e2 MC |
237 | } |
238 | ||
00e925c5 | 239 | uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 240 | { |
e1a29bbd WL |
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)); | |
f798f1e2 MC |
244 | } |
245 | ||
00e925c5 | 246 | uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 247 | { |
e1a29bbd WL |
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 ? | |
15161e42 CMC |
251 | float32_minnum(frs1, frs2, &env->fp_status) : |
252 | float32_minimum_number(frs1, frs2, &env->fp_status)); | |
f798f1e2 MC |
253 | } |
254 | ||
00e925c5 | 255 | uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 256 | { |
e1a29bbd WL |
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 ? | |
15161e42 CMC |
260 | float32_maxnum(frs1, frs2, &env->fp_status) : |
261 | float32_maximum_number(frs1, frs2, &env->fp_status)); | |
f798f1e2 MC |
262 | } |
263 | ||
00e925c5 | 264 | uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1) |
f798f1e2 | 265 | { |
e1a29bbd WL |
266 | float32 frs1 = check_nanbox_s(env, rs1); |
267 | return nanbox_s(env, float32_sqrt(frs1, &env->fp_status)); | |
f798f1e2 MC |
268 | } |
269 | ||
00e925c5 | 270 | target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 271 | { |
e1a29bbd WL |
272 | float32 frs1 = check_nanbox_s(env, rs1); |
273 | float32 frs2 = check_nanbox_s(env, rs2); | |
f798f1e2 MC |
274 | return float32_le(frs1, frs2, &env->fp_status); |
275 | } | |
276 | ||
00e925c5 | 277 | target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 278 | { |
e1a29bbd WL |
279 | float32 frs1 = check_nanbox_s(env, rs1); |
280 | float32 frs2 = check_nanbox_s(env, rs2); | |
f798f1e2 MC |
281 | return float32_lt(frs1, frs2, &env->fp_status); |
282 | } | |
283 | ||
00e925c5 | 284 | target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
f798f1e2 | 285 | { |
e1a29bbd WL |
286 | float32 frs1 = check_nanbox_s(env, rs1); |
287 | float32 frs2 = check_nanbox_s(env, rs2); | |
f798f1e2 MC |
288 | return float32_eq_quiet(frs1, frs2, &env->fp_status); |
289 | } | |
290 | ||
00e925c5 | 291 | target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t rs1) |
f798f1e2 | 292 | { |
e1a29bbd | 293 | float32 frs1 = check_nanbox_s(env, rs1); |
f798f1e2 MC |
294 | return float32_to_int32(frs1, &env->fp_status); |
295 | } | |
296 | ||
00e925c5 | 297 | target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1) |
f798f1e2 | 298 | { |
e1a29bbd | 299 | float32 frs1 = check_nanbox_s(env, rs1); |
f798f1e2 MC |
300 | return (int32_t)float32_to_uint32(frs1, &env->fp_status); |
301 | } | |
302 | ||
daf866b6 | 303 | target_ulong helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1) |
f798f1e2 | 304 | { |
e1a29bbd | 305 | float32 frs1 = check_nanbox_s(env, rs1); |
f798f1e2 MC |
306 | return float32_to_int64(frs1, &env->fp_status); |
307 | } | |
308 | ||
daf866b6 | 309 | target_ulong helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1) |
f798f1e2 | 310 | { |
e1a29bbd | 311 | float32 frs1 = check_nanbox_s(env, rs1); |
f798f1e2 MC |
312 | return float32_to_uint64(frs1, &env->fp_status); |
313 | } | |
f798f1e2 MC |
314 | |
315 | uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1) | |
316 | { | |
e1a29bbd | 317 | return nanbox_s(env, int32_to_float32((int32_t)rs1, &env->fp_status)); |
f798f1e2 MC |
318 | } |
319 | ||
320 | uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1) | |
321 | { | |
e1a29bbd | 322 | return nanbox_s(env, uint32_to_float32((uint32_t)rs1, &env->fp_status)); |
f798f1e2 MC |
323 | } |
324 | ||
daf866b6 | 325 | uint64_t helper_fcvt_s_l(CPURISCVState *env, target_ulong rs1) |
f798f1e2 | 326 | { |
e1a29bbd | 327 | return nanbox_s(env, int64_to_float32(rs1, &env->fp_status)); |
f798f1e2 MC |
328 | } |
329 | ||
daf866b6 | 330 | uint64_t helper_fcvt_s_lu(CPURISCVState *env, target_ulong rs1) |
f798f1e2 | 331 | { |
e1a29bbd | 332 | return nanbox_s(env, uint64_to_float32(rs1, &env->fp_status)); |
f798f1e2 | 333 | } |
f798f1e2 | 334 | |
e1a29bbd | 335 | target_ulong helper_fclass_s(CPURISCVState *env, uint64_t rs1) |
f798f1e2 | 336 | { |
e1a29bbd | 337 | float32 frs1 = check_nanbox_s(env, rs1); |
121ddbb3 | 338 | return fclass_s(frs1); |
f798f1e2 MC |
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 | { | |
15161e42 CMC |
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); | |
f798f1e2 MC |
366 | } |
367 | ||
368 | uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) | |
369 | { | |
15161e42 CMC |
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); | |
f798f1e2 MC |
373 | } |
374 | ||
375 | uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1) | |
376 | { | |
e1a29bbd | 377 | return nanbox_s(env, float64_to_float32(rs1, &env->fp_status)); |
f798f1e2 MC |
378 | } |
379 | ||
380 | uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1) | |
381 | { | |
e1a29bbd | 382 | float32 frs1 = check_nanbox_s(env, rs1); |
00e925c5 | 383 | return float32_to_float64(frs1, &env->fp_status); |
f798f1e2 MC |
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 | ||
daf866b6 | 416 | target_ulong helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1) |
f798f1e2 MC |
417 | { |
418 | return float64_to_int64(frs1, &env->fp_status); | |
419 | } | |
420 | ||
daf866b6 | 421 | target_ulong helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1) |
f798f1e2 MC |
422 | { |
423 | return float64_to_uint64(frs1, &env->fp_status); | |
424 | } | |
f798f1e2 MC |
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 | ||
daf866b6 | 436 | uint64_t helper_fcvt_d_l(CPURISCVState *env, target_ulong rs1) |
f798f1e2 MC |
437 | { |
438 | return int64_to_float64(rs1, &env->fp_status); | |
439 | } | |
440 | ||
daf866b6 | 441 | uint64_t helper_fcvt_d_lu(CPURISCVState *env, target_ulong rs1) |
f798f1e2 MC |
442 | { |
443 | return uint64_to_float64(rs1, &env->fp_status); | |
444 | } | |
f798f1e2 MC |
445 | |
446 | target_ulong helper_fclass_d(uint64_t frs1) | |
447 | { | |
121ddbb3 | 448 | return fclass_d(frs1); |
f798f1e2 | 449 | } |
00c1899f KC |
450 | |
451 | uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | |
452 | { | |
a2464a4c WL |
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)); | |
00c1899f KC |
456 | } |
457 | ||
458 | uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | |
459 | { | |
a2464a4c WL |
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)); | |
00c1899f KC |
463 | } |
464 | ||
465 | uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | |
466 | { | |
a2464a4c WL |
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)); | |
00c1899f KC |
470 | } |
471 | ||
472 | uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | |
473 | { | |
a2464a4c WL |
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)); | |
00c1899f KC |
477 | } |
478 | ||
479 | uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) | |
480 | { | |
a2464a4c WL |
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 ? | |
00c1899f KC |
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 | { | |
a2464a4c WL |
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 ? | |
00c1899f KC |
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 | { | |
a2464a4c WL |
499 | float16 frs1 = check_nanbox_h(env, rs1); |
500 | return nanbox_h(env, float16_sqrt(frs1, &env->fp_status)); | |
00c1899f | 501 | } |
7b03c8e5 | 502 | |
11f9c450 KC |
503 | target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2) |
504 | { | |
a2464a4c WL |
505 | float16 frs1 = check_nanbox_h(env, rs1); |
506 | float16 frs2 = check_nanbox_h(env, rs2); | |
11f9c450 KC |
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 | { | |
a2464a4c WL |
512 | float16 frs1 = check_nanbox_h(env, rs1); |
513 | float16 frs2 = check_nanbox_h(env, rs2); | |
11f9c450 KC |
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 | { | |
a2464a4c WL |
519 | float16 frs1 = check_nanbox_h(env, rs1); |
520 | float16 frs2 = check_nanbox_h(env, rs2); | |
11f9c450 KC |
521 | return float16_eq_quiet(frs1, frs2, &env->fp_status); |
522 | } | |
523 | ||
a2464a4c | 524 | target_ulong helper_fclass_h(CPURISCVState *env, uint64_t rs1) |
6bc6fc96 | 525 | { |
a2464a4c | 526 | float16 frs1 = check_nanbox_h(env, rs1); |
6bc6fc96 KC |
527 | return fclass_h(frs1); |
528 | } | |
529 | ||
7b03c8e5 KC |
530 | target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1) |
531 | { | |
a2464a4c | 532 | float16 frs1 = check_nanbox_h(env, rs1); |
7b03c8e5 KC |
533 | return float16_to_int32(frs1, &env->fp_status); |
534 | } | |
535 | ||
536 | target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1) | |
537 | { | |
a2464a4c | 538 | float16 frs1 = check_nanbox_h(env, rs1); |
7b03c8e5 KC |
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 | { | |
a2464a4c | 544 | float16 frs1 = check_nanbox_h(env, rs1); |
7b03c8e5 KC |
545 | return float16_to_int64(frs1, &env->fp_status); |
546 | } | |
547 | ||
548 | target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1) | |
549 | { | |
a2464a4c | 550 | float16 frs1 = check_nanbox_h(env, rs1); |
7b03c8e5 KC |
551 | return float16_to_uint64(frs1, &env->fp_status); |
552 | } | |
553 | ||
554 | uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1) | |
555 | { | |
a2464a4c | 556 | return nanbox_h(env, int32_to_float16((int32_t)rs1, &env->fp_status)); |
7b03c8e5 KC |
557 | } |
558 | ||
559 | uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1) | |
560 | { | |
a2464a4c | 561 | return nanbox_h(env, uint32_to_float16((uint32_t)rs1, &env->fp_status)); |
7b03c8e5 KC |
562 | } |
563 | ||
564 | uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1) | |
565 | { | |
a2464a4c | 566 | return nanbox_h(env, int64_to_float16(rs1, &env->fp_status)); |
7b03c8e5 KC |
567 | } |
568 | ||
569 | uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1) | |
570 | { | |
a2464a4c | 571 | return nanbox_h(env, uint64_to_float16(rs1, &env->fp_status)); |
7b03c8e5 KC |
572 | } |
573 | ||
574 | uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1) | |
575 | { | |
e1a29bbd | 576 | float32 frs1 = check_nanbox_s(env, rs1); |
a2464a4c | 577 | return nanbox_h(env, float32_to_float16(frs1, true, &env->fp_status)); |
7b03c8e5 KC |
578 | } |
579 | ||
580 | uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1) | |
581 | { | |
a2464a4c | 582 | float16 frs1 = check_nanbox_h(env, rs1); |
e1a29bbd | 583 | return nanbox_s(env, float16_to_float32(frs1, true, &env->fp_status)); |
7b03c8e5 KC |
584 | } |
585 | ||
586 | uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1) | |
587 | { | |
a2464a4c | 588 | return nanbox_h(env, float64_to_float16(rs1, true, &env->fp_status)); |
7b03c8e5 KC |
589 | } |
590 | ||
591 | uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1) | |
592 | { | |
a2464a4c | 593 | float16 frs1 = check_nanbox_h(env, rs1); |
7b03c8e5 KC |
594 | return float16_to_float64(frs1, true, &env->fp_status); |
595 | } |