]>
git.proxmox.com Git - mirror_qemu.git/blob - target/riscv/insn_trans/trans_rvf.inc.c
2 * RISC-V translation routines for the RV64F 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 #define REQUIRE_FPU do {\
22 if (ctx->mstatus_fs == 0) \
27 * RISC-V requires NaN-boxing of narrower width floating
28 * point values. This applies when a 32-bit value is
29 * assigned to a 64-bit FP register. Thus this does not
30 * apply when the RVD extension is not present.
32 static void gen_nanbox_fpr(DisasContext
*ctx
, int regno
)
34 if (has_ext(ctx
, RVD
)) {
35 tcg_gen_ori_i64(cpu_fpr
[regno
], cpu_fpr
[regno
],
36 MAKE_64BIT_MASK(32, 32));
40 static bool trans_flw(DisasContext
*ctx
, arg_flw
*a
)
42 TCGv t0
= tcg_temp_new();
43 gen_get_gpr(t0
, a
->rs1
);
45 REQUIRE_EXT(ctx
, RVF
);
46 tcg_gen_addi_tl(t0
, t0
, a
->imm
);
48 tcg_gen_qemu_ld_i64(cpu_fpr
[a
->rd
], t0
, ctx
->mem_idx
, MO_TEUL
);
49 gen_nanbox_fpr(ctx
, a
->rd
);
56 static bool trans_fsw(DisasContext
*ctx
, arg_fsw
*a
)
58 TCGv t0
= tcg_temp_new();
59 gen_get_gpr(t0
, a
->rs1
);
62 REQUIRE_EXT(ctx
, RVF
);
63 tcg_gen_addi_tl(t0
, t0
, a
->imm
);
65 tcg_gen_qemu_st_i64(cpu_fpr
[a
->rs2
], t0
, ctx
->mem_idx
, MO_TEUL
);
71 static bool trans_fmadd_s(DisasContext
*ctx
, arg_fmadd_s
*a
)
74 REQUIRE_EXT(ctx
, RVF
);
75 gen_set_rm(ctx
, a
->rm
);
76 gen_helper_fmadd_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
],
77 cpu_fpr
[a
->rs2
], cpu_fpr
[a
->rs3
]);
82 static bool trans_fmsub_s(DisasContext
*ctx
, arg_fmsub_s
*a
)
85 REQUIRE_EXT(ctx
, RVF
);
86 gen_set_rm(ctx
, a
->rm
);
87 gen_helper_fmsub_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
],
88 cpu_fpr
[a
->rs2
], cpu_fpr
[a
->rs3
]);
93 static bool trans_fnmsub_s(DisasContext
*ctx
, arg_fnmsub_s
*a
)
96 REQUIRE_EXT(ctx
, RVF
);
97 gen_set_rm(ctx
, a
->rm
);
98 gen_helper_fnmsub_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
],
99 cpu_fpr
[a
->rs2
], cpu_fpr
[a
->rs3
]);
104 static bool trans_fnmadd_s(DisasContext
*ctx
, arg_fnmadd_s
*a
)
107 REQUIRE_EXT(ctx
, RVF
);
108 gen_set_rm(ctx
, a
->rm
);
109 gen_helper_fnmadd_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
],
110 cpu_fpr
[a
->rs2
], cpu_fpr
[a
->rs3
]);
115 static bool trans_fadd_s(DisasContext
*ctx
, arg_fadd_s
*a
)
118 REQUIRE_EXT(ctx
, RVF
);
120 gen_set_rm(ctx
, a
->rm
);
121 gen_helper_fadd_s(cpu_fpr
[a
->rd
], cpu_env
,
122 cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
127 static bool trans_fsub_s(DisasContext
*ctx
, arg_fsub_s
*a
)
130 REQUIRE_EXT(ctx
, RVF
);
132 gen_set_rm(ctx
, a
->rm
);
133 gen_helper_fsub_s(cpu_fpr
[a
->rd
], cpu_env
,
134 cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
139 static bool trans_fmul_s(DisasContext
*ctx
, arg_fmul_s
*a
)
142 REQUIRE_EXT(ctx
, RVF
);
144 gen_set_rm(ctx
, a
->rm
);
145 gen_helper_fmul_s(cpu_fpr
[a
->rd
], cpu_env
,
146 cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
151 static bool trans_fdiv_s(DisasContext
*ctx
, arg_fdiv_s
*a
)
154 REQUIRE_EXT(ctx
, RVF
);
156 gen_set_rm(ctx
, a
->rm
);
157 gen_helper_fdiv_s(cpu_fpr
[a
->rd
], cpu_env
,
158 cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
163 static bool trans_fsqrt_s(DisasContext
*ctx
, arg_fsqrt_s
*a
)
166 REQUIRE_EXT(ctx
, RVF
);
168 gen_set_rm(ctx
, a
->rm
);
169 gen_helper_fsqrt_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
]);
174 static bool trans_fsgnj_s(DisasContext
*ctx
, arg_fsgnj_s
*a
)
177 REQUIRE_EXT(ctx
, RVF
);
178 if (a
->rs1
== a
->rs2
) { /* FMOV */
179 tcg_gen_mov_i64(cpu_fpr
[a
->rd
], cpu_fpr
[a
->rs1
]);
181 tcg_gen_deposit_i64(cpu_fpr
[a
->rd
], cpu_fpr
[a
->rs2
], cpu_fpr
[a
->rs1
],
188 static bool trans_fsgnjn_s(DisasContext
*ctx
, arg_fsgnjn_s
*a
)
191 REQUIRE_EXT(ctx
, RVF
);
192 if (a
->rs1
== a
->rs2
) { /* FNEG */
193 tcg_gen_xori_i64(cpu_fpr
[a
->rd
], cpu_fpr
[a
->rs1
], INT32_MIN
);
195 TCGv_i64 t0
= tcg_temp_new_i64();
196 tcg_gen_not_i64(t0
, cpu_fpr
[a
->rs2
]);
197 tcg_gen_deposit_i64(cpu_fpr
[a
->rd
], t0
, cpu_fpr
[a
->rs1
], 0, 31);
198 tcg_temp_free_i64(t0
);
204 static bool trans_fsgnjx_s(DisasContext
*ctx
, arg_fsgnjx_s
*a
)
207 REQUIRE_EXT(ctx
, RVF
);
208 if (a
->rs1
== a
->rs2
) { /* FABS */
209 tcg_gen_andi_i64(cpu_fpr
[a
->rd
], cpu_fpr
[a
->rs1
], ~INT32_MIN
);
211 TCGv_i64 t0
= tcg_temp_new_i64();
212 tcg_gen_andi_i64(t0
, cpu_fpr
[a
->rs2
], INT32_MIN
);
213 tcg_gen_xor_i64(cpu_fpr
[a
->rd
], cpu_fpr
[a
->rs1
], t0
);
214 tcg_temp_free_i64(t0
);
220 static bool trans_fmin_s(DisasContext
*ctx
, arg_fmin_s
*a
)
223 REQUIRE_EXT(ctx
, RVF
);
225 gen_helper_fmin_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
],
231 static bool trans_fmax_s(DisasContext
*ctx
, arg_fmax_s
*a
)
234 REQUIRE_EXT(ctx
, RVF
);
236 gen_helper_fmax_s(cpu_fpr
[a
->rd
], cpu_env
, cpu_fpr
[a
->rs1
],
242 static bool trans_fcvt_w_s(DisasContext
*ctx
, arg_fcvt_w_s
*a
)
245 REQUIRE_EXT(ctx
, RVF
);
247 TCGv t0
= tcg_temp_new();
248 gen_set_rm(ctx
, a
->rm
);
249 gen_helper_fcvt_w_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
]);
250 gen_set_gpr(a
->rd
, t0
);
256 static bool trans_fcvt_wu_s(DisasContext
*ctx
, arg_fcvt_wu_s
*a
)
259 REQUIRE_EXT(ctx
, RVF
);
261 TCGv t0
= tcg_temp_new();
262 gen_set_rm(ctx
, a
->rm
);
263 gen_helper_fcvt_wu_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
]);
264 gen_set_gpr(a
->rd
, t0
);
270 static bool trans_fmv_x_w(DisasContext
*ctx
, arg_fmv_x_w
*a
)
272 /* NOTE: This was FMV.X.S in an earlier version of the ISA spec! */
274 REQUIRE_EXT(ctx
, RVF
);
276 TCGv t0
= tcg_temp_new();
278 #if defined(TARGET_RISCV64)
279 tcg_gen_ext32s_tl(t0
, cpu_fpr
[a
->rs1
]);
281 tcg_gen_extrl_i64_i32(t0
, cpu_fpr
[a
->rs1
]);
284 gen_set_gpr(a
->rd
, t0
);
290 static bool trans_feq_s(DisasContext
*ctx
, arg_feq_s
*a
)
293 REQUIRE_EXT(ctx
, RVF
);
294 TCGv t0
= tcg_temp_new();
295 gen_helper_feq_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
296 gen_set_gpr(a
->rd
, t0
);
301 static bool trans_flt_s(DisasContext
*ctx
, arg_flt_s
*a
)
304 REQUIRE_EXT(ctx
, RVF
);
305 TCGv t0
= tcg_temp_new();
306 gen_helper_flt_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
307 gen_set_gpr(a
->rd
, t0
);
312 static bool trans_fle_s(DisasContext
*ctx
, arg_fle_s
*a
)
315 REQUIRE_EXT(ctx
, RVF
);
316 TCGv t0
= tcg_temp_new();
317 gen_helper_fle_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
], cpu_fpr
[a
->rs2
]);
318 gen_set_gpr(a
->rd
, t0
);
323 static bool trans_fclass_s(DisasContext
*ctx
, arg_fclass_s
*a
)
326 REQUIRE_EXT(ctx
, RVF
);
328 TCGv t0
= tcg_temp_new();
330 gen_helper_fclass_s(t0
, cpu_fpr
[a
->rs1
]);
332 gen_set_gpr(a
->rd
, t0
);
338 static bool trans_fcvt_s_w(DisasContext
*ctx
, arg_fcvt_s_w
*a
)
341 REQUIRE_EXT(ctx
, RVF
);
343 TCGv t0
= tcg_temp_new();
344 gen_get_gpr(t0
, a
->rs1
);
346 gen_set_rm(ctx
, a
->rm
);
347 gen_helper_fcvt_s_w(cpu_fpr
[a
->rd
], cpu_env
, t0
);
355 static bool trans_fcvt_s_wu(DisasContext
*ctx
, arg_fcvt_s_wu
*a
)
358 REQUIRE_EXT(ctx
, RVF
);
360 TCGv t0
= tcg_temp_new();
361 gen_get_gpr(t0
, a
->rs1
);
363 gen_set_rm(ctx
, a
->rm
);
364 gen_helper_fcvt_s_wu(cpu_fpr
[a
->rd
], cpu_env
, t0
);
372 static bool trans_fmv_w_x(DisasContext
*ctx
, arg_fmv_w_x
*a
)
374 /* NOTE: This was FMV.S.X in an earlier version of the ISA spec! */
376 REQUIRE_EXT(ctx
, RVF
);
378 TCGv t0
= tcg_temp_new();
379 gen_get_gpr(t0
, a
->rs1
);
381 #if defined(TARGET_RISCV64)
382 tcg_gen_mov_i64(cpu_fpr
[a
->rd
], t0
);
384 tcg_gen_extu_i32_i64(cpu_fpr
[a
->rd
], t0
);
393 #ifdef TARGET_RISCV64
394 static bool trans_fcvt_l_s(DisasContext
*ctx
, arg_fcvt_l_s
*a
)
397 REQUIRE_EXT(ctx
, RVF
);
399 TCGv t0
= tcg_temp_new();
400 gen_set_rm(ctx
, a
->rm
);
401 gen_helper_fcvt_l_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
]);
402 gen_set_gpr(a
->rd
, t0
);
407 static bool trans_fcvt_lu_s(DisasContext
*ctx
, arg_fcvt_lu_s
*a
)
410 REQUIRE_EXT(ctx
, RVF
);
412 TCGv t0
= tcg_temp_new();
413 gen_set_rm(ctx
, a
->rm
);
414 gen_helper_fcvt_lu_s(t0
, cpu_env
, cpu_fpr
[a
->rs1
]);
415 gen_set_gpr(a
->rd
, t0
);
420 static bool trans_fcvt_s_l(DisasContext
*ctx
, arg_fcvt_s_l
*a
)
423 REQUIRE_EXT(ctx
, RVF
);
425 TCGv t0
= tcg_temp_new();
426 gen_get_gpr(t0
, a
->rs1
);
428 gen_set_rm(ctx
, a
->rm
);
429 gen_helper_fcvt_s_l(cpu_fpr
[a
->rd
], cpu_env
, t0
);
436 static bool trans_fcvt_s_lu(DisasContext
*ctx
, arg_fcvt_s_lu
*a
)
439 REQUIRE_EXT(ctx
, RVF
);
441 TCGv t0
= tcg_temp_new();
442 gen_get_gpr(t0
, a
->rs1
);
444 gen_set_rm(ctx
, a
->rm
);
445 gen_helper_fcvt_s_lu(cpu_fpr
[a
->rd
], cpu_env
, t0
);