2 * RISC-V translation routines for the RVXI Base Integer Instruction Set.
4 * Copyright (c) 2020 Western Digital
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.
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
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/>.
19 #ifndef CONFIG_USER_ONLY
20 static void check_access(DisasContext *ctx) {
22 if (ctx->virt_enabled) {
23 generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
25 generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
31 static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
33 REQUIRE_EXT(ctx, RVH);
34 #ifndef CONFIG_USER_ONLY
35 TCGv t0 = tcg_temp_new();
36 TCGv t1 = tcg_temp_new();
40 gen_get_gpr(t0, a->rs1);
42 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
43 gen_set_gpr(a->rd, t1);
53 static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
55 REQUIRE_EXT(ctx, RVH);
56 #ifndef CONFIG_USER_ONLY
57 TCGv t0 = tcg_temp_new();
58 TCGv t1 = tcg_temp_new();
62 gen_get_gpr(t0, a->rs1);
64 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
65 gen_set_gpr(a->rd, t1);
75 static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
77 REQUIRE_EXT(ctx, RVH);
78 #ifndef CONFIG_USER_ONLY
79 TCGv t0 = tcg_temp_new();
80 TCGv t1 = tcg_temp_new();
84 gen_get_gpr(t0, a->rs1);
86 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
87 gen_set_gpr(a->rd, t1);
97 static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
99 REQUIRE_EXT(ctx, RVH);
100 #ifndef CONFIG_USER_ONLY
101 TCGv t0 = tcg_temp_new();
102 TCGv t1 = tcg_temp_new();
106 gen_get_gpr(t0, a->rs1);
108 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
109 gen_set_gpr(a->rd, t1);
119 static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
121 REQUIRE_EXT(ctx, RVH);
122 #ifndef CONFIG_USER_ONLY
123 TCGv t0 = tcg_temp_new();
124 TCGv t1 = tcg_temp_new();
128 gen_get_gpr(t0, a->rs1);
129 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
130 gen_set_gpr(a->rd, t1);
140 static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
142 REQUIRE_EXT(ctx, RVH);
143 #ifndef CONFIG_USER_ONLY
144 TCGv t0 = tcg_temp_new();
145 TCGv dat = tcg_temp_new();
149 gen_get_gpr(t0, a->rs1);
150 gen_get_gpr(dat, a->rs2);
152 tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
162 static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
164 REQUIRE_EXT(ctx, RVH);
165 #ifndef CONFIG_USER_ONLY
166 TCGv t0 = tcg_temp_new();
167 TCGv dat = tcg_temp_new();
171 gen_get_gpr(t0, a->rs1);
172 gen_get_gpr(dat, a->rs2);
174 tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
184 static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
186 REQUIRE_EXT(ctx, RVH);
187 #ifndef CONFIG_USER_ONLY
188 TCGv t0 = tcg_temp_new();
189 TCGv dat = tcg_temp_new();
193 gen_get_gpr(t0, a->rs1);
194 gen_get_gpr(dat, a->rs2);
196 tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
206 #ifdef TARGET_RISCV64
207 static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
209 REQUIRE_EXT(ctx, RVH);
210 #ifndef CONFIG_USER_ONLY
211 TCGv t0 = tcg_temp_new();
212 TCGv t1 = tcg_temp_new();
216 gen_get_gpr(t0, a->rs1);
218 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
219 gen_set_gpr(a->rd, t1);
229 static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
231 REQUIRE_EXT(ctx, RVH);
232 #ifndef CONFIG_USER_ONLY
233 TCGv t0 = tcg_temp_new();
234 TCGv t1 = tcg_temp_new();
238 gen_get_gpr(t0, a->rs1);
240 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
241 gen_set_gpr(a->rd, t1);
251 static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
253 REQUIRE_EXT(ctx, RVH);
254 #ifndef CONFIG_USER_ONLY
255 TCGv t0 = tcg_temp_new();
256 TCGv dat = tcg_temp_new();
260 gen_get_gpr(t0, a->rs1);
261 gen_get_gpr(dat, a->rs2);
263 tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
274 static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
276 REQUIRE_EXT(ctx, RVH);
277 #ifndef CONFIG_USER_ONLY
278 TCGv t0 = tcg_temp_new();
279 TCGv t1 = tcg_temp_new();
283 gen_get_gpr(t0, a->rs1);
285 gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
286 gen_set_gpr(a->rd, t1);
296 static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
298 REQUIRE_EXT(ctx, RVH);
299 #ifndef CONFIG_USER_ONLY
300 TCGv t0 = tcg_temp_new();
301 TCGv t1 = tcg_temp_new();
305 gen_get_gpr(t0, a->rs1);
307 gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
308 gen_set_gpr(a->rd, t1);
318 static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
320 REQUIRE_EXT(ctx, RVH);
321 #ifndef CONFIG_USER_ONLY
322 gen_helper_hyp_gvma_tlb_flush(cpu_env);
328 static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
330 REQUIRE_EXT(ctx, RVH);
331 #ifndef CONFIG_USER_ONLY
332 gen_helper_hyp_tlb_flush(cpu_env);