2 * RISC-V translation routines for the RV64D Standard Extension.
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de
6 * Bastian Koppelmann, kbastian@mail.uni-paderborn.de
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2 or later, as published by the Free Software Foundation.
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
21 static bool trans_fld(DisasContext *ctx, arg_fld *a)
24 REQUIRE_EXT(ctx, RVD);
25 TCGv t0 = tcg_temp_new();
26 gen_get_gpr(t0, a->rs1);
27 tcg_gen_addi_tl(t0, t0, a->imm);
29 tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
36 static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
39 REQUIRE_EXT(ctx, RVD);
40 TCGv t0 = tcg_temp_new();
41 gen_get_gpr(t0, a->rs1);
42 tcg_gen_addi_tl(t0, t0, a->imm);
44 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
50 static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
53 REQUIRE_EXT(ctx, RVD);
54 gen_set_rm(ctx, a->rm);
55 gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
56 cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
61 static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a)
64 REQUIRE_EXT(ctx, RVD);
65 gen_set_rm(ctx, a->rm);
66 gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
67 cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
72 static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a)
75 REQUIRE_EXT(ctx, RVD);
76 gen_set_rm(ctx, a->rm);
77 gen_helper_fnmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
78 cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
83 static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a)
86 REQUIRE_EXT(ctx, RVD);
87 gen_set_rm(ctx, a->rm);
88 gen_helper_fnmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
89 cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
94 static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a)
97 REQUIRE_EXT(ctx, RVD);
99 gen_set_rm(ctx, a->rm);
100 gen_helper_fadd_d(cpu_fpr[a->rd], cpu_env,
101 cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
107 static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a)
110 REQUIRE_EXT(ctx, RVD);
112 gen_set_rm(ctx, a->rm);
113 gen_helper_fsub_d(cpu_fpr[a->rd], cpu_env,
114 cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
120 static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a)
123 REQUIRE_EXT(ctx, RVD);
125 gen_set_rm(ctx, a->rm);
126 gen_helper_fmul_d(cpu_fpr[a->rd], cpu_env,
127 cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
133 static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a)
136 REQUIRE_EXT(ctx, RVD);
138 gen_set_rm(ctx, a->rm);
139 gen_helper_fdiv_d(cpu_fpr[a->rd], cpu_env,
140 cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
146 static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a)
149 REQUIRE_EXT(ctx, RVD);
151 gen_set_rm(ctx, a->rm);
152 gen_helper_fsqrt_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
158 static bool trans_fsgnj_d(DisasContext *ctx, arg_fsgnj_d *a)
160 if (a->rs1 == a->rs2) { /* FMOV */
161 tcg_gen_mov_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1]);
163 tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rs2],
164 cpu_fpr[a->rs1], 0, 63);
170 static bool trans_fsgnjn_d(DisasContext *ctx, arg_fsgnjn_d *a)
173 REQUIRE_EXT(ctx, RVD);
174 if (a->rs1 == a->rs2) { /* FNEG */
175 tcg_gen_xori_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], INT64_MIN);
177 TCGv_i64 t0 = tcg_temp_new_i64();
178 tcg_gen_not_i64(t0, cpu_fpr[a->rs2]);
179 tcg_gen_deposit_i64(cpu_fpr[a->rd], t0, cpu_fpr[a->rs1], 0, 63);
180 tcg_temp_free_i64(t0);
186 static bool trans_fsgnjx_d(DisasContext *ctx, arg_fsgnjx_d *a)
189 REQUIRE_EXT(ctx, RVD);
190 if (a->rs1 == a->rs2) { /* FABS */
191 tcg_gen_andi_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], ~INT64_MIN);
193 TCGv_i64 t0 = tcg_temp_new_i64();
194 tcg_gen_andi_i64(t0, cpu_fpr[a->rs2], INT64_MIN);
195 tcg_gen_xor_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], t0);
196 tcg_temp_free_i64(t0);
202 static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a)
205 REQUIRE_EXT(ctx, RVD);
207 gen_helper_fmin_d(cpu_fpr[a->rd], cpu_env,
208 cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
214 static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a)
217 REQUIRE_EXT(ctx, RVD);
219 gen_helper_fmax_d(cpu_fpr[a->rd], cpu_env,
220 cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
226 static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a)
229 REQUIRE_EXT(ctx, RVD);
231 gen_set_rm(ctx, a->rm);
232 gen_helper_fcvt_s_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
238 static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a)
241 REQUIRE_EXT(ctx, RVD);
243 gen_set_rm(ctx, a->rm);
244 gen_helper_fcvt_d_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
250 static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
253 REQUIRE_EXT(ctx, RVD);
255 TCGv t0 = tcg_temp_new();
256 gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
257 gen_set_gpr(a->rd, t0);
263 static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
266 REQUIRE_EXT(ctx, RVD);
268 TCGv t0 = tcg_temp_new();
269 gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
270 gen_set_gpr(a->rd, t0);
276 static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
279 REQUIRE_EXT(ctx, RVD);
281 TCGv t0 = tcg_temp_new();
282 gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
283 gen_set_gpr(a->rd, t0);
289 static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
292 REQUIRE_EXT(ctx, RVD);
294 TCGv t0 = tcg_temp_new();
295 gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
296 gen_set_gpr(a->rd, t0);
301 static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
304 REQUIRE_EXT(ctx, RVD);
306 TCGv t0 = tcg_temp_new();
307 gen_set_rm(ctx, a->rm);
308 gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
309 gen_set_gpr(a->rd, t0);
315 static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
318 REQUIRE_EXT(ctx, RVD);
320 TCGv t0 = tcg_temp_new();
321 gen_set_rm(ctx, a->rm);
322 gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
323 gen_set_gpr(a->rd, t0);
329 static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
332 REQUIRE_EXT(ctx, RVD);
334 TCGv t0 = tcg_temp_new();
335 gen_get_gpr(t0, a->rs1);
337 gen_set_rm(ctx, a->rm);
338 gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
345 static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
348 REQUIRE_EXT(ctx, RVD);
350 TCGv t0 = tcg_temp_new();
351 gen_get_gpr(t0, a->rs1);
353 gen_set_rm(ctx, a->rm);
354 gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
361 #ifdef TARGET_RISCV64
363 static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
366 REQUIRE_EXT(ctx, RVD);
368 TCGv t0 = tcg_temp_new();
369 gen_set_rm(ctx, a->rm);
370 gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
371 gen_set_gpr(a->rd, t0);
376 static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
379 REQUIRE_EXT(ctx, RVD);
381 TCGv t0 = tcg_temp_new();
382 gen_set_rm(ctx, a->rm);
383 gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
384 gen_set_gpr(a->rd, t0);
389 static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
392 REQUIRE_EXT(ctx, RVD);
394 gen_set_gpr(a->rd, cpu_fpr[a->rs1]);
398 static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
401 REQUIRE_EXT(ctx, RVD);
403 TCGv t0 = tcg_temp_new();
404 gen_get_gpr(t0, a->rs1);
406 gen_set_rm(ctx, a->rm);
407 gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
413 static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
416 REQUIRE_EXT(ctx, RVD);
418 TCGv t0 = tcg_temp_new();
419 gen_get_gpr(t0, a->rs1);
421 gen_set_rm(ctx, a->rm);
422 gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
428 static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
431 REQUIRE_EXT(ctx, RVD);
433 TCGv t0 = tcg_temp_new();
434 gen_get_gpr(t0, a->rs1);
436 tcg_gen_mov_tl(cpu_fpr[a->rd], t0);