]>
Commit | Line | Data |
---|---|---|
b8429ded AF |
1 | /* |
2 | * RISC-V translation routines for the RVXI Base Integer Instruction Set. | |
3 | * | |
4 | * Copyright (c) 2020 Western Digital | |
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 | ||
743077b3 | 19 | #ifndef CONFIG_USER_ONLY |
f33960df RH |
20 | static bool check_access(DisasContext *ctx) |
21 | { | |
743077b3 AF |
22 | if (!ctx->hlsx) { |
23 | if (ctx->virt_enabled) { | |
24 | generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT); | |
25 | } else { | |
26 | generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST); | |
27 | } | |
f33960df | 28 | return false; |
743077b3 | 29 | } |
f33960df | 30 | return true; |
743077b3 AF |
31 | } |
32 | #endif | |
33 | ||
f33960df | 34 | static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop) |
8c5362ac | 35 | { |
f33960df | 36 | #ifdef CONFIG_USER_ONLY |
8c5362ac | 37 | return false; |
f33960df RH |
38 | #else |
39 | if (check_access(ctx)) { | |
40 | TCGv dest = dest_gpr(ctx, a->rd); | |
41 | TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); | |
42 | int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK; | |
43 | tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop); | |
44 | gen_set_gpr(ctx, a->rd, dest); | |
45 | } | |
46 | return true; | |
8c5362ac AF |
47 | #endif |
48 | } | |
49 | ||
f33960df | 50 | static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a) |
8c5362ac AF |
51 | { |
52 | REQUIRE_EXT(ctx, RVH); | |
f33960df RH |
53 | return do_hlv(ctx, a, MO_SB); |
54 | } | |
8c5362ac | 55 | |
f33960df RH |
56 | static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a) |
57 | { | |
58 | REQUIRE_EXT(ctx, RVH); | |
59 | return do_hlv(ctx, a, MO_TESW); | |
8c5362ac AF |
60 | } |
61 | ||
62 | static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a) | |
63 | { | |
64 | REQUIRE_EXT(ctx, RVH); | |
f33960df | 65 | return do_hlv(ctx, a, MO_TESL); |
8c5362ac AF |
66 | } |
67 | ||
68 | static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a) | |
69 | { | |
70 | REQUIRE_EXT(ctx, RVH); | |
f33960df | 71 | return do_hlv(ctx, a, MO_UB); |
8c5362ac AF |
72 | } |
73 | ||
74 | static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a) | |
75 | { | |
76 | REQUIRE_EXT(ctx, RVH); | |
f33960df RH |
77 | return do_hlv(ctx, a, MO_TEUW); |
78 | } | |
8c5362ac | 79 | |
f33960df RH |
80 | static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop) |
81 | { | |
82 | #ifdef CONFIG_USER_ONLY | |
8c5362ac | 83 | return false; |
f33960df RH |
84 | #else |
85 | if (check_access(ctx)) { | |
86 | TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); | |
87 | TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); | |
88 | int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK; | |
89 | tcg_gen_qemu_st_tl(data, addr, mem_idx, mop); | |
90 | } | |
91 | return true; | |
8c5362ac AF |
92 | #endif |
93 | } | |
94 | ||
95 | static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a) | |
96 | { | |
97 | REQUIRE_EXT(ctx, RVH); | |
f33960df | 98 | return do_hsv(ctx, a, MO_SB); |
8c5362ac AF |
99 | } |
100 | ||
101 | static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a) | |
102 | { | |
103 | REQUIRE_EXT(ctx, RVH); | |
f33960df | 104 | return do_hsv(ctx, a, MO_TESW); |
8c5362ac AF |
105 | } |
106 | ||
107 | static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a) | |
108 | { | |
109 | REQUIRE_EXT(ctx, RVH); | |
f33960df | 110 | return do_hsv(ctx, a, MO_TESL); |
8c5362ac AF |
111 | } |
112 | ||
8c5362ac AF |
113 | static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a) |
114 | { | |
daf866b6 | 115 | REQUIRE_64BIT(ctx); |
8c5362ac | 116 | REQUIRE_EXT(ctx, RVH); |
f33960df | 117 | return do_hlv(ctx, a, MO_TEUL); |
8c5362ac AF |
118 | } |
119 | ||
120 | static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a) | |
121 | { | |
daf866b6 | 122 | REQUIRE_64BIT(ctx); |
8c5362ac | 123 | REQUIRE_EXT(ctx, RVH); |
fc313c64 | 124 | return do_hlv(ctx, a, MO_TEUQ); |
8c5362ac AF |
125 | } |
126 | ||
127 | static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a) | |
128 | { | |
daf866b6 | 129 | REQUIRE_64BIT(ctx); |
8c5362ac | 130 | REQUIRE_EXT(ctx, RVH); |
fc313c64 | 131 | return do_hsv(ctx, a, MO_TEUQ); |
f33960df | 132 | } |
daf866b6 | 133 | |
8c5362ac | 134 | #ifndef CONFIG_USER_ONLY |
f33960df RH |
135 | static bool do_hlvx(DisasContext *ctx, arg_r2 *a, |
136 | void (*func)(TCGv, TCGv_env, TCGv)) | |
137 | { | |
138 | if (check_access(ctx)) { | |
139 | TCGv dest = dest_gpr(ctx, a->rd); | |
140 | TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); | |
141 | func(dest, cpu_env, addr); | |
142 | gen_set_gpr(ctx, a->rd, dest); | |
143 | } | |
8c5362ac | 144 | return true; |
8c5362ac | 145 | } |
f33960df | 146 | #endif |
8c5362ac AF |
147 | |
148 | static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a) | |
149 | { | |
150 | REQUIRE_EXT(ctx, RVH); | |
151 | #ifndef CONFIG_USER_ONLY | |
f33960df | 152 | return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu); |
8c5362ac AF |
153 | #else |
154 | return false; | |
155 | #endif | |
156 | } | |
157 | ||
158 | static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a) | |
159 | { | |
160 | REQUIRE_EXT(ctx, RVH); | |
161 | #ifndef CONFIG_USER_ONLY | |
f33960df | 162 | return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu); |
8c5362ac AF |
163 | #else |
164 | return false; | |
165 | #endif | |
166 | } | |
167 | ||
b8429ded AF |
168 | static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a) |
169 | { | |
2761db5f | 170 | REQUIRE_EXT(ctx, RVH); |
b8429ded | 171 | #ifndef CONFIG_USER_ONLY |
a9814e3e | 172 | decode_save_opc(ctx); |
e39a8320 | 173 | gen_helper_hyp_gvma_tlb_flush(cpu_env); |
2761db5f | 174 | return true; |
b8429ded AF |
175 | #endif |
176 | return false; | |
177 | } | |
178 | ||
179 | static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a) | |
180 | { | |
2761db5f | 181 | REQUIRE_EXT(ctx, RVH); |
b8429ded | 182 | #ifndef CONFIG_USER_ONLY |
a9814e3e | 183 | decode_save_opc(ctx); |
2761db5f AF |
184 | gen_helper_hyp_tlb_flush(cpu_env); |
185 | return true; | |
b8429ded AF |
186 | #endif |
187 | return false; | |
188 | } |