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
)
23 TCGv t0
= tcg_temp_new();
24 gen_get_gpr(t0
, a
->rs1
);
26 REQUIRE_EXT(ctx
, RVD
);
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
)
38 TCGv t0
= tcg_temp_new();
39 gen_get_gpr(t0
, a
->rs1
);
41 REQUIRE_EXT(ctx
, RVD
);
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
);