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 19static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a) 20{ 21 REQUIRE_EXT(ctx, RVH); 22#ifndef CONFIG_USER_ONLY 23 TCGv t0 = tcg_temp_new(); 24 TCGv t1 = tcg_temp_new(); 25 TCGv mem_idx = tcg_temp_new(); 26 TCGv memop = tcg_temp_new(); 27 28 gen_get_gpr(t0, a->rs1); 29 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 30 tcg_gen_movi_tl(memop, MO_SB); 31 32 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 33 gen_set_gpr(a->rd, t1); 34 35 tcg_temp_free(t0); 36 tcg_temp_free(t1); 37 tcg_temp_free(mem_idx); 38 tcg_temp_free(memop); 39 return true; 40#else 41 return false; 42#endif 43} 44 45static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a) 46{ 47 REQUIRE_EXT(ctx, RVH); 48#ifndef CONFIG_USER_ONLY 49 TCGv t0 = tcg_temp_new(); 50 TCGv t1 = tcg_temp_new(); 51 TCGv mem_idx = tcg_temp_new(); 52 TCGv memop = tcg_temp_new(); 53 54 gen_get_gpr(t0, a->rs1); 55 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 56 tcg_gen_movi_tl(memop, MO_TESW); 57 58 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 59 gen_set_gpr(a->rd, t1); 60 61 tcg_temp_free(t0); 62 tcg_temp_free(t1); 63 tcg_temp_free(mem_idx); 64 tcg_temp_free(memop); 65 return true; 66#else 67 return false; 68#endif 69} 70 71static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a) 72{ 73 REQUIRE_EXT(ctx, RVH); 74#ifndef CONFIG_USER_ONLY 75 TCGv t0 = tcg_temp_new(); 76 TCGv t1 = tcg_temp_new(); 77 TCGv mem_idx = tcg_temp_new(); 78 TCGv memop = tcg_temp_new(); 79 80 gen_get_gpr(t0, a->rs1); 81 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 82 tcg_gen_movi_tl(memop, MO_TESL); 83 84 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 85 gen_set_gpr(a->rd, t1); 86 87 tcg_temp_free(t0); 88 tcg_temp_free(t1); 89 tcg_temp_free(mem_idx); 90 tcg_temp_free(memop); 91 return true; 92#else 93 return false; 94#endif 95} 96 97static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a) 98{ 99 REQUIRE_EXT(ctx, RVH); 100#ifndef CONFIG_USER_ONLY 101 TCGv t0 = tcg_temp_new(); 102 TCGv t1 = tcg_temp_new(); 103 TCGv mem_idx = tcg_temp_new(); 104 TCGv memop = tcg_temp_new(); 105 106 gen_get_gpr(t0, a->rs1); 107 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 108 tcg_gen_movi_tl(memop, MO_UB); 109 110 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 111 gen_set_gpr(a->rd, t1); 112 113 tcg_temp_free(t0); 114 tcg_temp_free(t1); 115 tcg_temp_free(mem_idx); 116 tcg_temp_free(memop); 117 return true; 118#else 119 return false; 120#endif 121} 122 123static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a) 124{ 125 REQUIRE_EXT(ctx, RVH); 126#ifndef CONFIG_USER_ONLY 127 TCGv t0 = tcg_temp_new(); 128 TCGv t1 = tcg_temp_new(); 129 TCGv mem_idx = tcg_temp_new(); 130 TCGv memop = tcg_temp_new(); 131 132 gen_get_gpr(t0, a->rs1); 133 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 134 tcg_gen_movi_tl(memop, MO_TEUW); 135 136 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 137 gen_set_gpr(a->rd, t1); 138 139 tcg_temp_free(t0); 140 tcg_temp_free(t1); 141 tcg_temp_free(mem_idx); 142 tcg_temp_free(memop); 143 return true; 144#else 145 return false; 146#endif 147} 148 149static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a) 150{ 151 REQUIRE_EXT(ctx, RVH); 152#ifndef CONFIG_USER_ONLY 153 TCGv t0 = tcg_temp_new(); 154 TCGv dat = tcg_temp_new(); 155 TCGv mem_idx = tcg_temp_new(); 156 TCGv memop = tcg_temp_new(); 157 158 gen_get_gpr(t0, a->rs1); 159 gen_get_gpr(dat, a->rs2); 160 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 161 tcg_gen_movi_tl(memop, MO_SB); 162 163 gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop); 164 165 tcg_temp_free(t0); 166 tcg_temp_free(dat); 167 tcg_temp_free(mem_idx); 168 tcg_temp_free(memop); 169 return true; 170#else 171 return false; 172#endif 173} 174 175static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a) 176{ 177 REQUIRE_EXT(ctx, RVH); 178#ifndef CONFIG_USER_ONLY 179 TCGv t0 = tcg_temp_new(); 180 TCGv dat = tcg_temp_new(); 181 TCGv mem_idx = tcg_temp_new(); 182 TCGv memop = tcg_temp_new(); 183 184 gen_get_gpr(t0, a->rs1); 185 gen_get_gpr(dat, a->rs2); 186 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 187 tcg_gen_movi_tl(memop, MO_TESW); 188 189 gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop); 190 191 tcg_temp_free(t0); 192 tcg_temp_free(dat); 193 tcg_temp_free(mem_idx); 194 tcg_temp_free(memop); 195 return true; 196#else 197 return false; 198#endif 199} 200 201static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a) 202{ 203 REQUIRE_EXT(ctx, RVH); 204#ifndef CONFIG_USER_ONLY 205 TCGv t0 = tcg_temp_new(); 206 TCGv dat = tcg_temp_new(); 207 TCGv mem_idx = tcg_temp_new(); 208 TCGv memop = tcg_temp_new(); 209 210 gen_get_gpr(t0, a->rs1); 211 gen_get_gpr(dat, a->rs2); 212 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 213 tcg_gen_movi_tl(memop, MO_TESL); 214 215 gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop); 216 217 tcg_temp_free(t0); 218 tcg_temp_free(dat); 219 tcg_temp_free(mem_idx); 220 tcg_temp_free(memop); 221 return true; 222#else 223 return false; 224#endif 225} 226 227#ifdef TARGET_RISCV64 228static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a) 229{ 230 REQUIRE_EXT(ctx, RVH); 231#ifndef CONFIG_USER_ONLY 232 TCGv t0 = tcg_temp_new(); 233 TCGv t1 = tcg_temp_new(); 234 TCGv mem_idx = tcg_temp_new(); 235 TCGv memop = tcg_temp_new(); 236 237 gen_get_gpr(t0, a->rs1); 238 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 239 tcg_gen_movi_tl(memop, MO_TEUL); 240 241 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 242 gen_set_gpr(a->rd, t1); 243 244 tcg_temp_free(t0); 245 tcg_temp_free(t1); 246 tcg_temp_free(mem_idx); 247 tcg_temp_free(memop); 248 return true; 249#else 250 return false; 251#endif 252} 253 254static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a) 255{ 256 REQUIRE_EXT(ctx, RVH); 257#ifndef CONFIG_USER_ONLY 258 TCGv t0 = tcg_temp_new(); 259 TCGv t1 = tcg_temp_new(); 260 TCGv mem_idx = tcg_temp_new(); 261 TCGv memop = tcg_temp_new(); 262 263 gen_get_gpr(t0, a->rs1); 264 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 265 tcg_gen_movi_tl(memop, MO_TEQ); 266 267 gen_helper_hyp_load(t1, cpu_env, t0, mem_idx, memop); 268 gen_set_gpr(a->rd, t1); 269 270 tcg_temp_free(t0); 271 tcg_temp_free(t1); 272 tcg_temp_free(mem_idx); 273 tcg_temp_free(memop); 274 return true; 275#else 276 return false; 277#endif 278} 279 280static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a) 281{ 282 REQUIRE_EXT(ctx, RVH); 283#ifndef CONFIG_USER_ONLY 284 TCGv t0 = tcg_temp_new(); 285 TCGv dat = tcg_temp_new(); 286 TCGv mem_idx = tcg_temp_new(); 287 TCGv memop = tcg_temp_new(); 288 289 gen_get_gpr(t0, a->rs1); 290 gen_get_gpr(dat, a->rs2); 291 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 292 tcg_gen_movi_tl(memop, MO_TEQ); 293 294 gen_helper_hyp_store(cpu_env, t0, dat, mem_idx, memop); 295 296 tcg_temp_free(t0); 297 tcg_temp_free(dat); 298 tcg_temp_free(mem_idx); 299 tcg_temp_free(memop); 300 return true; 301#else 302 return false; 303#endif 304} 305#endif 306 307static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a) 308{ 309 REQUIRE_EXT(ctx, RVH); 310#ifndef CONFIG_USER_ONLY 311 TCGv t0 = tcg_temp_new(); 312 TCGv t1 = tcg_temp_new(); 313 TCGv mem_idx = tcg_temp_new(); 314 TCGv memop = tcg_temp_new(); 315 316 gen_get_gpr(t0, a->rs1); 317 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 318 tcg_gen_movi_tl(memop, MO_TEUW); 319 320 gen_helper_hyp_x_load(t1, cpu_env, t0, mem_idx, memop); 321 gen_set_gpr(a->rd, t1); 322 323 tcg_temp_free(t0); 324 tcg_temp_free(t1); 325 tcg_temp_free(mem_idx); 326 tcg_temp_free(memop); 327 return true; 328#else 329 return false; 330#endif 331} 332 333static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a) 334{ 335 REQUIRE_EXT(ctx, RVH); 336#ifndef CONFIG_USER_ONLY 337 TCGv t0 = tcg_temp_new(); 338 TCGv t1 = tcg_temp_new(); 339 TCGv mem_idx = tcg_temp_new(); 340 TCGv memop = tcg_temp_new(); 341 342 gen_get_gpr(t0, a->rs1); 343 tcg_gen_movi_tl(mem_idx, ctx->mem_idx); 344 tcg_gen_movi_tl(memop, MO_TEUL); 345 346 gen_helper_hyp_x_load(t1, cpu_env, t0, mem_idx, memop); 347 gen_set_gpr(a->rd, t1); 348 349 tcg_temp_free(t0); 350 tcg_temp_free(t1); 351 tcg_temp_free(mem_idx); 352 tcg_temp_free(memop); 353 return true; 354#else 355 return false; 356#endif 357} 358 359static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a) 360{ 361 REQUIRE_EXT(ctx, RVH); 362#ifndef CONFIG_USER_ONLY 363 gen_helper_hyp_tlb_flush(cpu_env); 364 return true; 365#endif 366 return false; 367} 368 369static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a) 370{ 371 REQUIRE_EXT(ctx, RVH); 372#ifndef CONFIG_USER_ONLY 373 gen_helper_hyp_tlb_flush(cpu_env); 374 return true; 375#endif 376 return false; 377} 378