master
inc 166 lines 4.11 KB
Raw
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
23 static 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
29 static 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
35 static 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
41 static 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, 0);
48 func(dest, tcg_env, addr);
49 gen_set_gpr(ctx, a->rd, dest);
50 return true;
51 }
52
53 static 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, 0);
60 func(tcg_env, addr, data);
61 return true;
62 }
63 #endif /* CONFIG_USER_ONLY */
64
65 static 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
71 static 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
77 static 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
83 static 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
89 static 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
95 static 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
101 static 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
107 static 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
113 static 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
120 static 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
127 static 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
134 static 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
140 static 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
146 static 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, 0);
151 gen_helper_hyp_gvma_tlb_flush(tcg_env);
152 return true;
153 #endif
154 return false;
155 }
156
157 static 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, 0);
162 gen_helper_hyp_tlb_flush(tcg_env);
163 return true;
164 #endif
165 return false;
166 }