xref: /openbmc/qemu/target/riscv/translate.c (revision 5dacdbae)
1 /*
2  * RISC-V emulation for qemu: main translation routines.
3  *
4  * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
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 #include "qemu/osdep.h"
20 #include "qemu/log.h"
21 #include "cpu.h"
22 #include "tcg/tcg-op.h"
23 #include "disas/disas.h"
24 #include "exec/cpu_ldst.h"
25 #include "exec/exec-all.h"
26 #include "exec/helper-proto.h"
27 #include "exec/helper-gen.h"
28 
29 #include "exec/translator.h"
30 #include "exec/log.h"
31 
32 #include "instmap.h"
33 #include "internals.h"
34 
35 /* global register indices */
36 static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
37 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
38 static TCGv load_res;
39 static TCGv load_val;
40 /* globals for PM CSRs */
41 static TCGv pm_mask;
42 static TCGv pm_base;
43 
44 #include "exec/gen-icount.h"
45 
46 /*
47  * If an operation is being performed on less than TARGET_LONG_BITS,
48  * it may require the inputs to be sign- or zero-extended; which will
49  * depend on the exact operation being performed.
50  */
51 typedef enum {
52     EXT_NONE,
53     EXT_SIGN,
54     EXT_ZERO,
55 } DisasExtend;
56 
57 typedef struct DisasContext {
58     DisasContextBase base;
59     /* pc_succ_insn points to the instruction following base.pc_next */
60     target_ulong pc_succ_insn;
61     target_ulong priv_ver;
62     RISCVMXL misa_mxl_max;
63     RISCVMXL xl;
64     uint32_t misa_ext;
65     uint32_t opcode;
66     uint32_t mstatus_fs;
67     uint32_t mstatus_vs;
68     uint32_t mstatus_hs_fs;
69     uint32_t mstatus_hs_vs;
70     uint32_t mem_idx;
71     /* Remember the rounding mode encoded in the previous fp instruction,
72        which we have already installed into env->fp_status.  Or -1 for
73        no previous fp instruction.  Note that we exit the TB when writing
74        to any system register, which includes CSR_FRM, so we do not have
75        to reset this known value.  */
76     int frm;
77     RISCVMXL ol;
78     bool virt_enabled;
79     const RISCVCPUConfig *cfg_ptr;
80     bool hlsx;
81     /* vector extension */
82     bool vill;
83     /*
84      * Encode LMUL to lmul as follows:
85      *     LMUL    vlmul    lmul
86      *      1       000       0
87      *      2       001       1
88      *      4       010       2
89      *      8       011       3
90      *      -       100       -
91      *     1/8      101      -3
92      *     1/4      110      -2
93      *     1/2      111      -1
94      */
95     int8_t lmul;
96     uint8_t sew;
97     uint8_t vta;
98     bool cfg_vta_all_1s;
99     target_ulong vstart;
100     bool vl_eq_vlmax;
101     uint8_t ntemp;
102     CPUState *cs;
103     TCGv zero;
104     /* Space for 3 operands plus 1 extra for address computation. */
105     TCGv temp[4];
106     /* Space for 4 operands(1 dest and <=3 src) for float point computation */
107     TCGv_i64 ftemp[4];
108     uint8_t nftemp;
109     /* PointerMasking extension */
110     bool pm_mask_enabled;
111     bool pm_base_enabled;
112     /* TCG of the current insn_start */
113     TCGOp *insn_start;
114 } DisasContext;
115 
116 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
117 {
118     return ctx->misa_ext & ext;
119 }
120 
121 static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
122 {
123     return true;
124 }
125 
126 #define MATERIALISE_EXT_PREDICATE(ext)  \
127     static bool has_ ## ext ## _p(DisasContext *ctx)    \
128     { \
129         return ctx->cfg_ptr->ext_ ## ext ; \
130     }
131 
132 MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
133 
134 #ifdef TARGET_RISCV32
135 #define get_xl(ctx)    MXL_RV32
136 #elif defined(CONFIG_USER_ONLY)
137 #define get_xl(ctx)    MXL_RV64
138 #else
139 #define get_xl(ctx)    ((ctx)->xl)
140 #endif
141 
142 /* The word size for this machine mode. */
143 static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
144 {
145     return 16 << get_xl(ctx);
146 }
147 
148 /* The operation length, as opposed to the xlen. */
149 #ifdef TARGET_RISCV32
150 #define get_ol(ctx)    MXL_RV32
151 #else
152 #define get_ol(ctx)    ((ctx)->ol)
153 #endif
154 
155 static inline int get_olen(DisasContext *ctx)
156 {
157     return 16 << get_ol(ctx);
158 }
159 
160 /* The maximum register length */
161 #ifdef TARGET_RISCV32
162 #define get_xl_max(ctx)    MXL_RV32
163 #else
164 #define get_xl_max(ctx)    ((ctx)->misa_mxl_max)
165 #endif
166 
167 /*
168  * RISC-V requires NaN-boxing of narrower width floating point values.
169  * This applies when a 32-bit value is assigned to a 64-bit FP register.
170  * For consistency and simplicity, we nanbox results even when the RVD
171  * extension is not present.
172  */
173 static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
174 {
175     tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32));
176 }
177 
178 static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in)
179 {
180     tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(16, 48));
181 }
182 
183 /*
184  * A narrow n-bit operation, where n < FLEN, checks that input operands
185  * are correctly Nan-boxed, i.e., all upper FLEN - n bits are 1.
186  * If so, the least-significant bits of the input are used, otherwise the
187  * input value is treated as an n-bit canonical NaN (v2.2 section 9.2).
188  *
189  * Here, the result is always nan-boxed, even the canonical nan.
190  */
191 static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
192 {
193     TCGv_i64 t_max = tcg_const_i64(0xffffffffffff0000ull);
194     TCGv_i64 t_nan = tcg_const_i64(0xffffffffffff7e00ull);
195 
196     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
197     tcg_temp_free_i64(t_max);
198     tcg_temp_free_i64(t_nan);
199 }
200 
201 static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
202 {
203     TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
204     TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
205 
206     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
207 }
208 
209 static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
210 {
211     if (get_xl(ctx) == MXL_RV32) {
212         dest = (int32_t)dest;
213     }
214     tcg_gen_movi_tl(cpu_pc, dest);
215 }
216 
217 static void gen_set_pc(DisasContext *ctx, TCGv dest)
218 {
219     if (get_xl(ctx) == MXL_RV32) {
220         tcg_gen_ext32s_tl(cpu_pc, dest);
221     } else {
222         tcg_gen_mov_tl(cpu_pc, dest);
223     }
224 }
225 
226 static void generate_exception(DisasContext *ctx, int excp)
227 {
228     gen_set_pc_imm(ctx, ctx->base.pc_next);
229     gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
230     ctx->base.is_jmp = DISAS_NORETURN;
231 }
232 
233 static void gen_exception_illegal(DisasContext *ctx)
234 {
235     tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
236                    offsetof(CPURISCVState, bins));
237     generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
238 }
239 
240 static void gen_exception_inst_addr_mis(DisasContext *ctx)
241 {
242     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
243     generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
244 }
245 
246 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
247 {
248     if (translator_use_goto_tb(&ctx->base, dest)) {
249         tcg_gen_goto_tb(n);
250         gen_set_pc_imm(ctx, dest);
251         tcg_gen_exit_tb(ctx->base.tb, n);
252     } else {
253         gen_set_pc_imm(ctx, dest);
254         tcg_gen_lookup_and_goto_ptr();
255     }
256 }
257 
258 /*
259  * Wrappers for getting reg values.
260  *
261  * The $zero register does not have cpu_gpr[0] allocated -- we supply the
262  * constant zero as a source, and an uninitialized sink as destination.
263  *
264  * Further, we may provide an extension for word operations.
265  */
266 static TCGv temp_new(DisasContext *ctx)
267 {
268     assert(ctx->ntemp < ARRAY_SIZE(ctx->temp));
269     return ctx->temp[ctx->ntemp++] = tcg_temp_new();
270 }
271 
272 static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
273 {
274     TCGv t;
275 
276     if (reg_num == 0) {
277         return ctx->zero;
278     }
279 
280     switch (get_ol(ctx)) {
281     case MXL_RV32:
282         switch (ext) {
283         case EXT_NONE:
284             break;
285         case EXT_SIGN:
286             t = temp_new(ctx);
287             tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
288             return t;
289         case EXT_ZERO:
290             t = temp_new(ctx);
291             tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
292             return t;
293         default:
294             g_assert_not_reached();
295         }
296         break;
297     case MXL_RV64:
298     case MXL_RV128:
299         break;
300     default:
301         g_assert_not_reached();
302     }
303     return cpu_gpr[reg_num];
304 }
305 
306 static TCGv get_gprh(DisasContext *ctx, int reg_num)
307 {
308     assert(get_xl(ctx) == MXL_RV128);
309     if (reg_num == 0) {
310         return ctx->zero;
311     }
312     return cpu_gprh[reg_num];
313 }
314 
315 static TCGv dest_gpr(DisasContext *ctx, int reg_num)
316 {
317     if (reg_num == 0 || get_olen(ctx) < TARGET_LONG_BITS) {
318         return temp_new(ctx);
319     }
320     return cpu_gpr[reg_num];
321 }
322 
323 static TCGv dest_gprh(DisasContext *ctx, int reg_num)
324 {
325     if (reg_num == 0) {
326         return temp_new(ctx);
327     }
328     return cpu_gprh[reg_num];
329 }
330 
331 static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
332 {
333     if (reg_num != 0) {
334         switch (get_ol(ctx)) {
335         case MXL_RV32:
336             tcg_gen_ext32s_tl(cpu_gpr[reg_num], t);
337             break;
338         case MXL_RV64:
339         case MXL_RV128:
340             tcg_gen_mov_tl(cpu_gpr[reg_num], t);
341             break;
342         default:
343             g_assert_not_reached();
344         }
345 
346         if (get_xl_max(ctx) == MXL_RV128) {
347             tcg_gen_sari_tl(cpu_gprh[reg_num], cpu_gpr[reg_num], 63);
348         }
349     }
350 }
351 
352 static void gen_set_gpri(DisasContext *ctx, int reg_num, target_long imm)
353 {
354     if (reg_num != 0) {
355         switch (get_ol(ctx)) {
356         case MXL_RV32:
357             tcg_gen_movi_tl(cpu_gpr[reg_num], (int32_t)imm);
358             break;
359         case MXL_RV64:
360         case MXL_RV128:
361             tcg_gen_movi_tl(cpu_gpr[reg_num], imm);
362             break;
363         default:
364             g_assert_not_reached();
365         }
366 
367         if (get_xl_max(ctx) == MXL_RV128) {
368             tcg_gen_movi_tl(cpu_gprh[reg_num], -(imm < 0));
369         }
370     }
371 }
372 
373 static void gen_set_gpr128(DisasContext *ctx, int reg_num, TCGv rl, TCGv rh)
374 {
375     assert(get_ol(ctx) == MXL_RV128);
376     if (reg_num != 0) {
377         tcg_gen_mov_tl(cpu_gpr[reg_num], rl);
378         tcg_gen_mov_tl(cpu_gprh[reg_num], rh);
379     }
380 }
381 
382 static TCGv_i64 ftemp_new(DisasContext *ctx)
383 {
384     assert(ctx->nftemp < ARRAY_SIZE(ctx->ftemp));
385     return ctx->ftemp[ctx->nftemp++] = tcg_temp_new_i64();
386 }
387 
388 static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num)
389 {
390     if (!ctx->cfg_ptr->ext_zfinx) {
391         return cpu_fpr[reg_num];
392     }
393 
394     if (reg_num == 0) {
395         return tcg_constant_i64(0);
396     }
397     switch (get_xl(ctx)) {
398     case MXL_RV32:
399 #ifdef TARGET_RISCV32
400     {
401         TCGv_i64 t = ftemp_new(ctx);
402         tcg_gen_ext_i32_i64(t, cpu_gpr[reg_num]);
403         return t;
404     }
405 #else
406     /* fall through */
407     case MXL_RV64:
408         return cpu_gpr[reg_num];
409 #endif
410     default:
411         g_assert_not_reached();
412     }
413 }
414 
415 static TCGv_i64 get_fpr_d(DisasContext *ctx, int reg_num)
416 {
417     if (!ctx->cfg_ptr->ext_zfinx) {
418         return cpu_fpr[reg_num];
419     }
420 
421     if (reg_num == 0) {
422         return tcg_constant_i64(0);
423     }
424     switch (get_xl(ctx)) {
425     case MXL_RV32:
426     {
427         TCGv_i64 t = ftemp_new(ctx);
428         tcg_gen_concat_tl_i64(t, cpu_gpr[reg_num], cpu_gpr[reg_num + 1]);
429         return t;
430     }
431 #ifdef TARGET_RISCV64
432     case MXL_RV64:
433         return cpu_gpr[reg_num];
434 #endif
435     default:
436         g_assert_not_reached();
437     }
438 }
439 
440 static TCGv_i64 dest_fpr(DisasContext *ctx, int reg_num)
441 {
442     if (!ctx->cfg_ptr->ext_zfinx) {
443         return cpu_fpr[reg_num];
444     }
445 
446     if (reg_num == 0) {
447         return ftemp_new(ctx);
448     }
449 
450     switch (get_xl(ctx)) {
451     case MXL_RV32:
452         return ftemp_new(ctx);
453 #ifdef TARGET_RISCV64
454     case MXL_RV64:
455         return cpu_gpr[reg_num];
456 #endif
457     default:
458         g_assert_not_reached();
459     }
460 }
461 
462 /* assume t is nanboxing (for normal) or sign-extended (for zfinx) */
463 static void gen_set_fpr_hs(DisasContext *ctx, int reg_num, TCGv_i64 t)
464 {
465     if (!ctx->cfg_ptr->ext_zfinx) {
466         tcg_gen_mov_i64(cpu_fpr[reg_num], t);
467         return;
468     }
469     if (reg_num != 0) {
470         switch (get_xl(ctx)) {
471         case MXL_RV32:
472 #ifdef TARGET_RISCV32
473             tcg_gen_extrl_i64_i32(cpu_gpr[reg_num], t);
474             break;
475 #else
476         /* fall through */
477         case MXL_RV64:
478             tcg_gen_mov_i64(cpu_gpr[reg_num], t);
479             break;
480 #endif
481         default:
482             g_assert_not_reached();
483         }
484     }
485 }
486 
487 static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t)
488 {
489     if (!ctx->cfg_ptr->ext_zfinx) {
490         tcg_gen_mov_i64(cpu_fpr[reg_num], t);
491         return;
492     }
493 
494     if (reg_num != 0) {
495         switch (get_xl(ctx)) {
496         case MXL_RV32:
497 #ifdef TARGET_RISCV32
498             tcg_gen_extr_i64_i32(cpu_gpr[reg_num], cpu_gpr[reg_num + 1], t);
499             break;
500 #else
501             tcg_gen_ext32s_i64(cpu_gpr[reg_num], t);
502             tcg_gen_sari_i64(cpu_gpr[reg_num + 1], t, 32);
503             break;
504         case MXL_RV64:
505             tcg_gen_mov_i64(cpu_gpr[reg_num], t);
506             break;
507 #endif
508         default:
509             g_assert_not_reached();
510         }
511     }
512 }
513 
514 static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
515 {
516     target_ulong next_pc;
517 
518     /* check misaligned: */
519     next_pc = ctx->base.pc_next + imm;
520     if (!has_ext(ctx, RVC)) {
521         if ((next_pc & 0x3) != 0) {
522             gen_exception_inst_addr_mis(ctx);
523             return;
524         }
525     }
526 
527     gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
528     gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
529     ctx->base.is_jmp = DISAS_NORETURN;
530 }
531 
532 /* Compute a canonical address from a register plus offset. */
533 static TCGv get_address(DisasContext *ctx, int rs1, int imm)
534 {
535     TCGv addr = temp_new(ctx);
536     TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
537 
538     tcg_gen_addi_tl(addr, src1, imm);
539     if (ctx->pm_mask_enabled) {
540         tcg_gen_and_tl(addr, addr, pm_mask);
541     } else if (get_xl(ctx) == MXL_RV32) {
542         tcg_gen_ext32u_tl(addr, addr);
543     }
544     if (ctx->pm_base_enabled) {
545         tcg_gen_or_tl(addr, addr, pm_base);
546     }
547     return addr;
548 }
549 
550 #ifndef CONFIG_USER_ONLY
551 /* The states of mstatus_fs are:
552  * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
553  * We will have already diagnosed disabled state,
554  * and need to turn initial/clean into dirty.
555  */
556 static void mark_fs_dirty(DisasContext *ctx)
557 {
558     TCGv tmp;
559 
560     if (!has_ext(ctx, RVF)) {
561         return;
562     }
563 
564     if (ctx->mstatus_fs != MSTATUS_FS) {
565         /* Remember the state change for the rest of the TB. */
566         ctx->mstatus_fs = MSTATUS_FS;
567 
568         tmp = tcg_temp_new();
569         tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
570         tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
571         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
572         tcg_temp_free(tmp);
573     }
574 
575     if (ctx->virt_enabled && ctx->mstatus_hs_fs != MSTATUS_FS) {
576         /* Remember the stage change for the rest of the TB. */
577         ctx->mstatus_hs_fs = MSTATUS_FS;
578 
579         tmp = tcg_temp_new();
580         tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
581         tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
582         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
583         tcg_temp_free(tmp);
584     }
585 }
586 #else
587 static inline void mark_fs_dirty(DisasContext *ctx) { }
588 #endif
589 
590 #ifndef CONFIG_USER_ONLY
591 /* The states of mstatus_vs are:
592  * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
593  * We will have already diagnosed disabled state,
594  * and need to turn initial/clean into dirty.
595  */
596 static void mark_vs_dirty(DisasContext *ctx)
597 {
598     TCGv tmp;
599 
600     if (ctx->mstatus_vs != MSTATUS_VS) {
601         /* Remember the state change for the rest of the TB.  */
602         ctx->mstatus_vs = MSTATUS_VS;
603 
604         tmp = tcg_temp_new();
605         tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
606         tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
607         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
608         tcg_temp_free(tmp);
609     }
610 
611     if (ctx->virt_enabled && ctx->mstatus_hs_vs != MSTATUS_VS) {
612         /* Remember the stage change for the rest of the TB. */
613         ctx->mstatus_hs_vs = MSTATUS_VS;
614 
615         tmp = tcg_temp_new();
616         tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
617         tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
618         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
619         tcg_temp_free(tmp);
620     }
621 }
622 #else
623 static inline void mark_vs_dirty(DisasContext *ctx) { }
624 #endif
625 
626 static void gen_set_rm(DisasContext *ctx, int rm)
627 {
628     if (ctx->frm == rm) {
629         return;
630     }
631     ctx->frm = rm;
632 
633     if (rm == RISCV_FRM_ROD) {
634         gen_helper_set_rod_rounding_mode(cpu_env);
635         return;
636     }
637 
638     gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
639 }
640 
641 static int ex_plus_1(DisasContext *ctx, int nf)
642 {
643     return nf + 1;
644 }
645 
646 #define EX_SH(amount) \
647     static int ex_shift_##amount(DisasContext *ctx, int imm) \
648     {                                         \
649         return imm << amount;                 \
650     }
651 EX_SH(1)
652 EX_SH(2)
653 EX_SH(3)
654 EX_SH(4)
655 EX_SH(12)
656 
657 #define REQUIRE_EXT(ctx, ext) do { \
658     if (!has_ext(ctx, ext)) {      \
659         return false;              \
660     }                              \
661 } while (0)
662 
663 #define REQUIRE_32BIT(ctx) do {    \
664     if (get_xl(ctx) != MXL_RV32) { \
665         return false;              \
666     }                              \
667 } while (0)
668 
669 #define REQUIRE_64BIT(ctx) do {     \
670     if (get_xl(ctx) != MXL_RV64) {  \
671         return false;               \
672     }                               \
673 } while (0)
674 
675 #define REQUIRE_128BIT(ctx) do {    \
676     if (get_xl(ctx) != MXL_RV128) { \
677         return false;               \
678     }                               \
679 } while (0)
680 
681 #define REQUIRE_64_OR_128BIT(ctx) do { \
682     if (get_xl(ctx) == MXL_RV32) {     \
683         return false;                  \
684     }                                  \
685 } while (0)
686 
687 #define REQUIRE_EITHER_EXT(ctx, A, B) do {       \
688     if (!ctx->cfg_ptr->ext_##A &&      \
689         !ctx->cfg_ptr->ext_##B) {      \
690         return false;                            \
691     }                                            \
692 } while (0)
693 
694 static int ex_rvc_register(DisasContext *ctx, int reg)
695 {
696     return 8 + reg;
697 }
698 
699 static int ex_rvc_shifti(DisasContext *ctx, int imm)
700 {
701     /* For RV128 a shamt of 0 means a shift by 64. */
702     return imm ? imm : 64;
703 }
704 
705 /* Include the auto-generated decoder for 32 bit insn */
706 #include "decode-insn32.c.inc"
707 
708 static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
709                              void (*func)(TCGv, TCGv, target_long))
710 {
711     TCGv dest = dest_gpr(ctx, a->rd);
712     TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
713 
714     func(dest, src1, a->imm);
715 
716     if (get_xl(ctx) == MXL_RV128) {
717         TCGv src1h = get_gprh(ctx, a->rs1);
718         TCGv desth = dest_gprh(ctx, a->rd);
719 
720         func(desth, src1h, -(a->imm < 0));
721         gen_set_gpr128(ctx, a->rd, dest, desth);
722     } else {
723         gen_set_gpr(ctx, a->rd, dest);
724     }
725 
726     return true;
727 }
728 
729 static bool gen_logic(DisasContext *ctx, arg_r *a,
730                       void (*func)(TCGv, TCGv, TCGv))
731 {
732     TCGv dest = dest_gpr(ctx, a->rd);
733     TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
734     TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
735 
736     func(dest, src1, src2);
737 
738     if (get_xl(ctx) == MXL_RV128) {
739         TCGv src1h = get_gprh(ctx, a->rs1);
740         TCGv src2h = get_gprh(ctx, a->rs2);
741         TCGv desth = dest_gprh(ctx, a->rd);
742 
743         func(desth, src1h, src2h);
744         gen_set_gpr128(ctx, a->rd, dest, desth);
745     } else {
746         gen_set_gpr(ctx, a->rd, dest);
747     }
748 
749     return true;
750 }
751 
752 static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext,
753                              void (*func)(TCGv, TCGv, target_long),
754                              void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long))
755 {
756     TCGv dest = dest_gpr(ctx, a->rd);
757     TCGv src1 = get_gpr(ctx, a->rs1, ext);
758 
759     if (get_ol(ctx) < MXL_RV128) {
760         func(dest, src1, a->imm);
761         gen_set_gpr(ctx, a->rd, dest);
762     } else {
763         if (f128 == NULL) {
764             return false;
765         }
766 
767         TCGv src1h = get_gprh(ctx, a->rs1);
768         TCGv desth = dest_gprh(ctx, a->rd);
769 
770         f128(dest, desth, src1, src1h, a->imm);
771         gen_set_gpr128(ctx, a->rd, dest, desth);
772     }
773     return true;
774 }
775 
776 static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext,
777                              void (*func)(TCGv, TCGv, TCGv),
778                              void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
779 {
780     TCGv dest = dest_gpr(ctx, a->rd);
781     TCGv src1 = get_gpr(ctx, a->rs1, ext);
782     TCGv src2 = tcg_constant_tl(a->imm);
783 
784     if (get_ol(ctx) < MXL_RV128) {
785         func(dest, src1, src2);
786         gen_set_gpr(ctx, a->rd, dest);
787     } else {
788         if (f128 == NULL) {
789             return false;
790         }
791 
792         TCGv src1h = get_gprh(ctx, a->rs1);
793         TCGv src2h = tcg_constant_tl(-(a->imm < 0));
794         TCGv desth = dest_gprh(ctx, a->rd);
795 
796         f128(dest, desth, src1, src1h, src2, src2h);
797         gen_set_gpr128(ctx, a->rd, dest, desth);
798     }
799     return true;
800 }
801 
802 static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
803                       void (*func)(TCGv, TCGv, TCGv),
804                       void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
805 {
806     TCGv dest = dest_gpr(ctx, a->rd);
807     TCGv src1 = get_gpr(ctx, a->rs1, ext);
808     TCGv src2 = get_gpr(ctx, a->rs2, ext);
809 
810     if (get_ol(ctx) < MXL_RV128) {
811         func(dest, src1, src2);
812         gen_set_gpr(ctx, a->rd, dest);
813     } else {
814         if (f128 == NULL) {
815             return false;
816         }
817 
818         TCGv src1h = get_gprh(ctx, a->rs1);
819         TCGv src2h = get_gprh(ctx, a->rs2);
820         TCGv desth = dest_gprh(ctx, a->rd);
821 
822         f128(dest, desth, src1, src1h, src2, src2h);
823         gen_set_gpr128(ctx, a->rd, dest, desth);
824     }
825     return true;
826 }
827 
828 static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
829                              void (*f_tl)(TCGv, TCGv, TCGv),
830                              void (*f_32)(TCGv, TCGv, TCGv),
831                              void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
832 {
833     int olen = get_olen(ctx);
834 
835     if (olen != TARGET_LONG_BITS) {
836         if (olen == 32) {
837             f_tl = f_32;
838         } else if (olen != 128) {
839             g_assert_not_reached();
840         }
841     }
842     return gen_arith(ctx, a, ext, f_tl, f_128);
843 }
844 
845 static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
846                              void (*func)(TCGv, TCGv, target_long),
847                              void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long))
848 {
849     TCGv dest, src1;
850     int max_len = get_olen(ctx);
851 
852     if (a->shamt >= max_len) {
853         return false;
854     }
855 
856     dest = dest_gpr(ctx, a->rd);
857     src1 = get_gpr(ctx, a->rs1, ext);
858 
859     if (max_len < 128) {
860         func(dest, src1, a->shamt);
861         gen_set_gpr(ctx, a->rd, dest);
862     } else {
863         TCGv src1h = get_gprh(ctx, a->rs1);
864         TCGv desth = dest_gprh(ctx, a->rd);
865 
866         if (f128 == NULL) {
867             return false;
868         }
869         f128(dest, desth, src1, src1h, a->shamt);
870         gen_set_gpr128(ctx, a->rd, dest, desth);
871     }
872     return true;
873 }
874 
875 static bool gen_shift_imm_fn_per_ol(DisasContext *ctx, arg_shift *a,
876                                     DisasExtend ext,
877                                     void (*f_tl)(TCGv, TCGv, target_long),
878                                     void (*f_32)(TCGv, TCGv, target_long),
879                                     void (*f_128)(TCGv, TCGv, TCGv, TCGv,
880                                                   target_long))
881 {
882     int olen = get_olen(ctx);
883     if (olen != TARGET_LONG_BITS) {
884         if (olen == 32) {
885             f_tl = f_32;
886         } else if (olen != 128) {
887             g_assert_not_reached();
888         }
889     }
890     return gen_shift_imm_fn(ctx, a, ext, f_tl, f_128);
891 }
892 
893 static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
894                              void (*func)(TCGv, TCGv, TCGv))
895 {
896     TCGv dest, src1, src2;
897     int max_len = get_olen(ctx);
898 
899     if (a->shamt >= max_len) {
900         return false;
901     }
902 
903     dest = dest_gpr(ctx, a->rd);
904     src1 = get_gpr(ctx, a->rs1, ext);
905     src2 = tcg_constant_tl(a->shamt);
906 
907     func(dest, src1, src2);
908 
909     gen_set_gpr(ctx, a->rd, dest);
910     return true;
911 }
912 
913 static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
914                       void (*func)(TCGv, TCGv, TCGv),
915                       void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv))
916 {
917     TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
918     TCGv ext2 = tcg_temp_new();
919     int max_len = get_olen(ctx);
920 
921     tcg_gen_andi_tl(ext2, src2, max_len - 1);
922 
923     TCGv dest = dest_gpr(ctx, a->rd);
924     TCGv src1 = get_gpr(ctx, a->rs1, ext);
925 
926     if (max_len < 128) {
927         func(dest, src1, ext2);
928         gen_set_gpr(ctx, a->rd, dest);
929     } else {
930         TCGv src1h = get_gprh(ctx, a->rs1);
931         TCGv desth = dest_gprh(ctx, a->rd);
932 
933         if (f128 == NULL) {
934             return false;
935         }
936         f128(dest, desth, src1, src1h, ext2);
937         gen_set_gpr128(ctx, a->rd, dest, desth);
938     }
939     tcg_temp_free(ext2);
940     return true;
941 }
942 
943 static bool gen_shift_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
944                              void (*f_tl)(TCGv, TCGv, TCGv),
945                              void (*f_32)(TCGv, TCGv, TCGv),
946                              void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv))
947 {
948     int olen = get_olen(ctx);
949     if (olen != TARGET_LONG_BITS) {
950         if (olen == 32) {
951             f_tl = f_32;
952         } else if (olen != 128) {
953             g_assert_not_reached();
954         }
955     }
956     return gen_shift(ctx, a, ext, f_tl, f_128);
957 }
958 
959 static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
960                       void (*func)(TCGv, TCGv))
961 {
962     TCGv dest = dest_gpr(ctx, a->rd);
963     TCGv src1 = get_gpr(ctx, a->rs1, ext);
964 
965     func(dest, src1);
966 
967     gen_set_gpr(ctx, a->rd, dest);
968     return true;
969 }
970 
971 static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
972                              void (*f_tl)(TCGv, TCGv),
973                              void (*f_32)(TCGv, TCGv))
974 {
975     int olen = get_olen(ctx);
976 
977     if (olen != TARGET_LONG_BITS) {
978         if (olen == 32) {
979             f_tl = f_32;
980         } else {
981             g_assert_not_reached();
982         }
983     }
984     return gen_unary(ctx, a, ext, f_tl);
985 }
986 
987 static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
988 {
989     DisasContext *ctx = container_of(dcbase, DisasContext, base);
990     CPUState *cpu = ctx->cs;
991     CPURISCVState *env = cpu->env_ptr;
992 
993     return cpu_ldl_code(env, pc);
994 }
995 
996 /* Include insn module translation function */
997 #include "insn_trans/trans_rvi.c.inc"
998 #include "insn_trans/trans_rvm.c.inc"
999 #include "insn_trans/trans_rva.c.inc"
1000 #include "insn_trans/trans_rvf.c.inc"
1001 #include "insn_trans/trans_rvd.c.inc"
1002 #include "insn_trans/trans_rvh.c.inc"
1003 #include "insn_trans/trans_rvv.c.inc"
1004 #include "insn_trans/trans_rvb.c.inc"
1005 #include "insn_trans/trans_rvzfh.c.inc"
1006 #include "insn_trans/trans_rvk.c.inc"
1007 #include "insn_trans/trans_privileged.c.inc"
1008 #include "insn_trans/trans_svinval.c.inc"
1009 #include "insn_trans/trans_xventanacondops.c.inc"
1010 
1011 /* Include the auto-generated decoder for 16 bit insn */
1012 #include "decode-insn16.c.inc"
1013 /* Include decoders for factored-out extensions */
1014 #include "decode-XVentanaCondOps.c.inc"
1015 
1016 static inline void decode_save_opc(DisasContext *ctx, target_ulong opc)
1017 {
1018     assert(ctx->insn_start != NULL);
1019     tcg_set_insn_start_param(ctx->insn_start, 1, opc);
1020     ctx->insn_start = NULL;
1021 }
1022 
1023 static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
1024 {
1025     /*
1026      * A table with predicate (i.e., guard) functions and decoder functions
1027      * that are tested in-order until a decoder matches onto the opcode.
1028      */
1029     static const struct {
1030         bool (*guard_func)(DisasContext *);
1031         bool (*decode_func)(DisasContext *, uint32_t);
1032     } decoders[] = {
1033         { always_true_p,  decode_insn32 },
1034         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
1035     };
1036 
1037     /* Check for compressed insn */
1038     if (extract16(opcode, 0, 2) != 3) {
1039         decode_save_opc(ctx, opcode);
1040         if (!has_ext(ctx, RVC)) {
1041             gen_exception_illegal(ctx);
1042         } else {
1043             ctx->opcode = opcode;
1044             ctx->pc_succ_insn = ctx->base.pc_next + 2;
1045             if (decode_insn16(ctx, opcode)) {
1046                 return;
1047             }
1048         }
1049     } else {
1050         uint32_t opcode32 = opcode;
1051         opcode32 = deposit32(opcode32, 16, 16,
1052                              translator_lduw(env, &ctx->base,
1053                                              ctx->base.pc_next + 2));
1054         decode_save_opc(ctx, opcode32);
1055         ctx->opcode = opcode32;
1056         ctx->pc_succ_insn = ctx->base.pc_next + 4;
1057 
1058         for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
1059             if (decoders[i].guard_func(ctx) &&
1060                 decoders[i].decode_func(ctx, opcode32)) {
1061                 return;
1062             }
1063         }
1064     }
1065 
1066     gen_exception_illegal(ctx);
1067 }
1068 
1069 static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
1070 {
1071     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1072     CPURISCVState *env = cs->env_ptr;
1073     RISCVCPU *cpu = RISCV_CPU(cs);
1074     uint32_t tb_flags = ctx->base.tb->flags;
1075 
1076     ctx->pc_succ_insn = ctx->base.pc_first;
1077     ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
1078     ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
1079     ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
1080     ctx->priv_ver = env->priv_ver;
1081 #if !defined(CONFIG_USER_ONLY)
1082     if (riscv_has_ext(env, RVH)) {
1083         ctx->virt_enabled = riscv_cpu_virt_enabled(env);
1084     } else {
1085         ctx->virt_enabled = false;
1086     }
1087 #else
1088     ctx->virt_enabled = false;
1089 #endif
1090     ctx->misa_ext = env->misa_ext;
1091     ctx->frm = -1;  /* unknown rounding mode */
1092     ctx->cfg_ptr = &(cpu->cfg);
1093     ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
1094     ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS);
1095     ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
1096     ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
1097     ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
1098     ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
1099     ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
1100     ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
1101     ctx->vstart = env->vstart;
1102     ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
1103     ctx->misa_mxl_max = env->misa_mxl_max;
1104     ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
1105     ctx->cs = cs;
1106     ctx->ntemp = 0;
1107     memset(ctx->temp, 0, sizeof(ctx->temp));
1108     ctx->nftemp = 0;
1109     memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
1110     ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
1111     ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
1112     ctx->zero = tcg_constant_tl(0);
1113 }
1114 
1115 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
1116 {
1117 }
1118 
1119 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1120 {
1121     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1122 
1123     tcg_gen_insn_start(ctx->base.pc_next, 0);
1124     ctx->insn_start = tcg_last_op();
1125 }
1126 
1127 static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1128 {
1129     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1130     CPURISCVState *env = cpu->env_ptr;
1131     uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next);
1132     int i;
1133 
1134     ctx->ol = ctx->xl;
1135     decode_opc(env, ctx, opcode16);
1136     ctx->base.pc_next = ctx->pc_succ_insn;
1137 
1138     for (i = ctx->ntemp - 1; i >= 0; --i) {
1139         tcg_temp_free(ctx->temp[i]);
1140         ctx->temp[i] = NULL;
1141     }
1142     ctx->ntemp = 0;
1143     for (i = ctx->nftemp - 1; i >= 0; --i) {
1144         tcg_temp_free_i64(ctx->ftemp[i]);
1145         ctx->ftemp[i] = NULL;
1146     }
1147     ctx->nftemp = 0;
1148 
1149     if (ctx->base.is_jmp == DISAS_NEXT) {
1150         target_ulong page_start;
1151 
1152         page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
1153         if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
1154             ctx->base.is_jmp = DISAS_TOO_MANY;
1155         }
1156     }
1157 }
1158 
1159 static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1160 {
1161     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1162 
1163     switch (ctx->base.is_jmp) {
1164     case DISAS_TOO_MANY:
1165         gen_goto_tb(ctx, 0, ctx->base.pc_next);
1166         break;
1167     case DISAS_NORETURN:
1168         break;
1169     default:
1170         g_assert_not_reached();
1171     }
1172 }
1173 
1174 static void riscv_tr_disas_log(const DisasContextBase *dcbase,
1175                                CPUState *cpu, FILE *logfile)
1176 {
1177 #ifndef CONFIG_USER_ONLY
1178     RISCVCPU *rvcpu = RISCV_CPU(cpu);
1179     CPURISCVState *env = &rvcpu->env;
1180 #endif
1181 
1182     fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
1183 #ifndef CONFIG_USER_ONLY
1184     fprintf(logfile, "Priv: "TARGET_FMT_ld"; Virt: "TARGET_FMT_ld"\n",
1185             env->priv, env->virt);
1186 #endif
1187     target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
1188 }
1189 
1190 static const TranslatorOps riscv_tr_ops = {
1191     .init_disas_context = riscv_tr_init_disas_context,
1192     .tb_start           = riscv_tr_tb_start,
1193     .insn_start         = riscv_tr_insn_start,
1194     .translate_insn     = riscv_tr_translate_insn,
1195     .tb_stop            = riscv_tr_tb_stop,
1196     .disas_log          = riscv_tr_disas_log,
1197 };
1198 
1199 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
1200 {
1201     DisasContext ctx;
1202 
1203     translator_loop(&riscv_tr_ops, &ctx.base, cs, tb, max_insns);
1204 }
1205 
1206 void riscv_translate_init(void)
1207 {
1208     int i;
1209 
1210     /*
1211      * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
1212      * Use the gen_set_gpr and get_gpr helper functions when accessing regs,
1213      * unless you specifically block reads/writes to reg 0.
1214      */
1215     cpu_gpr[0] = NULL;
1216     cpu_gprh[0] = NULL;
1217 
1218     for (i = 1; i < 32; i++) {
1219         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
1220             offsetof(CPURISCVState, gpr[i]), riscv_int_regnames[i]);
1221         cpu_gprh[i] = tcg_global_mem_new(cpu_env,
1222             offsetof(CPURISCVState, gprh[i]), riscv_int_regnamesh[i]);
1223     }
1224 
1225     for (i = 0; i < 32; i++) {
1226         cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
1227             offsetof(CPURISCVState, fpr[i]), riscv_fpr_regnames[i]);
1228     }
1229 
1230     cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, pc), "pc");
1231     cpu_vl = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, vl), "vl");
1232     cpu_vstart = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, vstart),
1233                             "vstart");
1234     load_res = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_res),
1235                              "load_res");
1236     load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
1237                              "load_val");
1238     /* Assign PM CSRs to tcg globals */
1239     pm_mask = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmmask),
1240                                  "pmmask");
1241     pm_base = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmbase),
1242                                  "pmbase");
1243 }
1244