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 19#ifdef CONFIG_USER_ONLY 20#define do_hlv(ctx, a, func) false 21#define do_hsv(ctx, a, func) false 22#else 23static void gen_helper_hyp_hlv_b(TCGv r, TCGv_env e, TCGv a) 24{ 25 gen_helper_hyp_hlv_bu(r, e, a); 26 tcg_gen_ext8s_tl(r, r); 27} 28 29static void gen_helper_hyp_hlv_h(TCGv r, TCGv_env e, TCGv a) 30{ 31 gen_helper_hyp_hlv_hu(r, e, a); 32 tcg_gen_ext16s_tl(r, r); 33} 34 35static void gen_helper_hyp_hlv_w(TCGv r, TCGv_env e, TCGv a) 36{ 37 gen_helper_hyp_hlv_wu(r, e, a); 38 tcg_gen_ext32s_tl(r, r); 39} 40 41static bool do_hlv(DisasContext *ctx, arg_r2 *a, 42 void (*func)(TCGv, TCGv_env, TCGv)) 43{ 44 TCGv dest = dest_gpr(ctx, a->rd); 45 TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); 46 47 decode_save_opc(ctx); 48 func(dest, tcg_env, addr); 49 gen_set_gpr(ctx, a->rd, dest); 50 return true; 51} 52 53static bool do_hsv(DisasContext *ctx, arg_r2_s *a, 54 void (*func)(TCGv_env, TCGv, TCGv)) 55{ 56 TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE); 57 TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); 58 59 decode_save_opc(ctx); 60 func(tcg_env, addr, data); 61 return true; 62} 63#endif /* CONFIG_USER_ONLY */ 64 65static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a) 66{ 67 REQUIRE_EXT(ctx, RVH); 68 return do_hlv(ctx, a, gen_helper_hyp_hlv_b); 69} 70 71static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a) 72{ 73 REQUIRE_EXT(ctx, RVH); 74 return do_hlv(ctx, a, gen_helper_hyp_hlv_h); 75} 76 77static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a) 78{ 79 REQUIRE_EXT(ctx, RVH); 80 return do_hlv(ctx, a, gen_helper_hyp_hlv_w); 81} 82 83static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a) 84{ 85 REQUIRE_EXT(ctx, RVH); 86 return do_hlv(ctx, a, gen_helper_hyp_hlv_bu); 87} 88 89static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a) 90{ 91 REQUIRE_EXT(ctx, RVH); 92 return do_hlv(ctx, a, gen_helper_hyp_hlv_hu); 93} 94 95static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a) 96{ 97 REQUIRE_EXT(ctx, RVH); 98 return do_hsv(ctx, a, gen_helper_hyp_hsv_b); 99} 100 101static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a) 102{ 103 REQUIRE_EXT(ctx, RVH); 104 return do_hsv(ctx, a, gen_helper_hyp_hsv_h); 105} 106 107static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a) 108{ 109 REQUIRE_EXT(ctx, RVH); 110 return do_hsv(ctx, a, gen_helper_hyp_hsv_w); 111} 112 113static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a) 114{ 115 REQUIRE_64BIT(ctx); 116 REQUIRE_EXT(ctx, RVH); 117 return do_hlv(ctx, a, gen_helper_hyp_hlv_wu); 118} 119 120static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a) 121{ 122 REQUIRE_64BIT(ctx); 123 REQUIRE_EXT(ctx, RVH); 124 return do_hlv(ctx, a, gen_helper_hyp_hlv_d); 125} 126 127static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a) 128{ 129 REQUIRE_64BIT(ctx); 130 REQUIRE_EXT(ctx, RVH); 131 return do_hsv(ctx, a, gen_helper_hyp_hsv_d); 132} 133 134static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a) 135{ 136 REQUIRE_EXT(ctx, RVH); 137 return do_hlv(ctx, a, gen_helper_hyp_hlvx_hu); 138} 139 140static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a) 141{ 142 REQUIRE_EXT(ctx, RVH); 143 return do_hlv(ctx, a, gen_helper_hyp_hlvx_wu); 144} 145 146static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a) 147{ 148 REQUIRE_EXT(ctx, RVH); 149#ifndef CONFIG_USER_ONLY 150 decode_save_opc(ctx); 151 gen_helper_hyp_gvma_tlb_flush(tcg_env); 152 return true; 153#endif 154 return false; 155} 156 157static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a) 158{ 159 REQUIRE_EXT(ctx, RVH); 160#ifndef CONFIG_USER_ONLY 161 decode_save_opc(ctx); 162 gen_helper_hyp_tlb_flush(tcg_env); 163 return true; 164#endif 165 return false; 166} 167