xref: /openbmc/qemu/target/riscv/translate.c (revision 40cf6a54)
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-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 
34 /* global register indices */
35 static TCGv cpu_gpr[32], cpu_pc;
36 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
37 static TCGv load_res;
38 static TCGv load_val;
39 
40 #include "exec/gen-icount.h"
41 
42 typedef struct DisasContext {
43     DisasContextBase base;
44     /* pc_succ_insn points to the instruction following base.pc_next */
45     target_ulong pc_succ_insn;
46     uint32_t opcode;
47     uint32_t flags;
48     uint32_t mem_idx;
49     /* Remember the rounding mode encoded in the previous fp instruction,
50        which we have already installed into env->fp_status.  Or -1 for
51        no previous fp instruction.  Note that we exit the TB when writing
52        to any system register, which includes CSR_FRM, so we do not have
53        to reset this known value.  */
54     int frm;
55 } DisasContext;
56 
57 /* convert riscv funct3 to qemu memop for load/store */
58 static const int tcg_memop_lookup[8] = {
59     [0 ... 7] = -1,
60     [0] = MO_SB,
61     [1] = MO_TESW,
62     [2] = MO_TESL,
63     [4] = MO_UB,
64     [5] = MO_TEUW,
65 #ifdef TARGET_RISCV64
66     [3] = MO_TEQ,
67     [6] = MO_TEUL,
68 #endif
69 };
70 
71 #ifdef TARGET_RISCV64
72 #define CASE_OP_32_64(X) case X: case glue(X, W)
73 #else
74 #define CASE_OP_32_64(X) case X
75 #endif
76 
77 static void generate_exception(DisasContext *ctx, int excp)
78 {
79     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
80     TCGv_i32 helper_tmp = tcg_const_i32(excp);
81     gen_helper_raise_exception(cpu_env, helper_tmp);
82     tcg_temp_free_i32(helper_tmp);
83     ctx->base.is_jmp = DISAS_NORETURN;
84 }
85 
86 static void generate_exception_mbadaddr(DisasContext *ctx, int excp)
87 {
88     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
89     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
90     TCGv_i32 helper_tmp = tcg_const_i32(excp);
91     gen_helper_raise_exception(cpu_env, helper_tmp);
92     tcg_temp_free_i32(helper_tmp);
93     ctx->base.is_jmp = DISAS_NORETURN;
94 }
95 
96 static void gen_exception_debug(void)
97 {
98     TCGv_i32 helper_tmp = tcg_const_i32(EXCP_DEBUG);
99     gen_helper_raise_exception(cpu_env, helper_tmp);
100     tcg_temp_free_i32(helper_tmp);
101 }
102 
103 static void gen_exception_illegal(DisasContext *ctx)
104 {
105     generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
106 }
107 
108 static void gen_exception_inst_addr_mis(DisasContext *ctx)
109 {
110     generate_exception_mbadaddr(ctx, RISCV_EXCP_INST_ADDR_MIS);
111 }
112 
113 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
114 {
115     if (unlikely(ctx->base.singlestep_enabled)) {
116         return false;
117     }
118 
119 #ifndef CONFIG_USER_ONLY
120     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
121 #else
122     return true;
123 #endif
124 }
125 
126 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
127 {
128     if (use_goto_tb(ctx, dest)) {
129         /* chaining is only allowed when the jump is to the same page */
130         tcg_gen_goto_tb(n);
131         tcg_gen_movi_tl(cpu_pc, dest);
132         tcg_gen_exit_tb(ctx->base.tb, n);
133     } else {
134         tcg_gen_movi_tl(cpu_pc, dest);
135         if (ctx->base.singlestep_enabled) {
136             gen_exception_debug();
137         } else {
138             tcg_gen_lookup_and_goto_ptr();
139         }
140     }
141 }
142 
143 /* Wrapper for getting reg values - need to check of reg is zero since
144  * cpu_gpr[0] is not actually allocated
145  */
146 static inline void gen_get_gpr(TCGv t, int reg_num)
147 {
148     if (reg_num == 0) {
149         tcg_gen_movi_tl(t, 0);
150     } else {
151         tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
152     }
153 }
154 
155 /* Wrapper for setting reg values - need to check of reg is zero since
156  * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
157  * since we usually avoid calling the OP_TYPE_gen function if we see a write to
158  * $zero
159  */
160 static inline void gen_set_gpr(int reg_num_dst, TCGv t)
161 {
162     if (reg_num_dst != 0) {
163         tcg_gen_mov_tl(cpu_gpr[reg_num_dst], t);
164     }
165 }
166 
167 static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
168 {
169     TCGv rl = tcg_temp_new();
170     TCGv rh = tcg_temp_new();
171 
172     tcg_gen_mulu2_tl(rl, rh, arg1, arg2);
173     /* fix up for one negative */
174     tcg_gen_sari_tl(rl, arg1, TARGET_LONG_BITS - 1);
175     tcg_gen_and_tl(rl, rl, arg2);
176     tcg_gen_sub_tl(ret, rh, rl);
177 
178     tcg_temp_free(rl);
179     tcg_temp_free(rh);
180 }
181 
182 static void gen_fsgnj(DisasContext *ctx, uint32_t rd, uint32_t rs1,
183     uint32_t rs2, int rm, uint64_t min)
184 {
185     switch (rm) {
186     case 0: /* fsgnj */
187         if (rs1 == rs2) { /* FMOV */
188             tcg_gen_mov_i64(cpu_fpr[rd], cpu_fpr[rs1]);
189         } else {
190             tcg_gen_deposit_i64(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1],
191                                 0, min == INT32_MIN ? 31 : 63);
192         }
193         break;
194     case 1: /* fsgnjn */
195         if (rs1 == rs2) { /* FNEG */
196             tcg_gen_xori_i64(cpu_fpr[rd], cpu_fpr[rs1], min);
197         } else {
198             TCGv_i64 t0 = tcg_temp_new_i64();
199             tcg_gen_not_i64(t0, cpu_fpr[rs2]);
200             tcg_gen_deposit_i64(cpu_fpr[rd], t0, cpu_fpr[rs1],
201                                 0, min == INT32_MIN ? 31 : 63);
202             tcg_temp_free_i64(t0);
203         }
204         break;
205     case 2: /* fsgnjx */
206         if (rs1 == rs2) { /* FABS */
207             tcg_gen_andi_i64(cpu_fpr[rd], cpu_fpr[rs1], ~min);
208         } else {
209             TCGv_i64 t0 = tcg_temp_new_i64();
210             tcg_gen_andi_i64(t0, cpu_fpr[rs2], min);
211             tcg_gen_xor_i64(cpu_fpr[rd], cpu_fpr[rs1], t0);
212             tcg_temp_free_i64(t0);
213         }
214         break;
215     default:
216         gen_exception_illegal(ctx);
217     }
218 }
219 
220 static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
221         int rs2)
222 {
223     TCGv source1, source2, cond1, cond2, zeroreg, resultopt1;
224     source1 = tcg_temp_new();
225     source2 = tcg_temp_new();
226     gen_get_gpr(source1, rs1);
227     gen_get_gpr(source2, rs2);
228 
229     switch (opc) {
230     CASE_OP_32_64(OPC_RISC_ADD):
231         tcg_gen_add_tl(source1, source1, source2);
232         break;
233     CASE_OP_32_64(OPC_RISC_SUB):
234         tcg_gen_sub_tl(source1, source1, source2);
235         break;
236 #if defined(TARGET_RISCV64)
237     case OPC_RISC_SLLW:
238         tcg_gen_andi_tl(source2, source2, 0x1F);
239         tcg_gen_shl_tl(source1, source1, source2);
240         break;
241 #endif
242     case OPC_RISC_SLL:
243         tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
244         tcg_gen_shl_tl(source1, source1, source2);
245         break;
246     case OPC_RISC_SLT:
247         tcg_gen_setcond_tl(TCG_COND_LT, source1, source1, source2);
248         break;
249     case OPC_RISC_SLTU:
250         tcg_gen_setcond_tl(TCG_COND_LTU, source1, source1, source2);
251         break;
252     case OPC_RISC_XOR:
253         tcg_gen_xor_tl(source1, source1, source2);
254         break;
255 #if defined(TARGET_RISCV64)
256     case OPC_RISC_SRLW:
257         /* clear upper 32 */
258         tcg_gen_ext32u_tl(source1, source1);
259         tcg_gen_andi_tl(source2, source2, 0x1F);
260         tcg_gen_shr_tl(source1, source1, source2);
261         break;
262 #endif
263     case OPC_RISC_SRL:
264         tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
265         tcg_gen_shr_tl(source1, source1, source2);
266         break;
267 #if defined(TARGET_RISCV64)
268     case OPC_RISC_SRAW:
269         /* first, trick to get it to act like working on 32 bits (get rid of
270         upper 32, sign extend to fill space) */
271         tcg_gen_ext32s_tl(source1, source1);
272         tcg_gen_andi_tl(source2, source2, 0x1F);
273         tcg_gen_sar_tl(source1, source1, source2);
274         break;
275 #endif
276     case OPC_RISC_SRA:
277         tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
278         tcg_gen_sar_tl(source1, source1, source2);
279         break;
280     case OPC_RISC_OR:
281         tcg_gen_or_tl(source1, source1, source2);
282         break;
283     case OPC_RISC_AND:
284         tcg_gen_and_tl(source1, source1, source2);
285         break;
286     CASE_OP_32_64(OPC_RISC_MUL):
287         tcg_gen_mul_tl(source1, source1, source2);
288         break;
289     case OPC_RISC_MULH:
290         tcg_gen_muls2_tl(source2, source1, source1, source2);
291         break;
292     case OPC_RISC_MULHSU:
293         gen_mulhsu(source1, source1, source2);
294         break;
295     case OPC_RISC_MULHU:
296         tcg_gen_mulu2_tl(source2, source1, source1, source2);
297         break;
298 #if defined(TARGET_RISCV64)
299     case OPC_RISC_DIVW:
300         tcg_gen_ext32s_tl(source1, source1);
301         tcg_gen_ext32s_tl(source2, source2);
302         /* fall through to DIV */
303 #endif
304     case OPC_RISC_DIV:
305         /* Handle by altering args to tcg_gen_div to produce req'd results:
306          * For overflow: want source1 in source1 and 1 in source2
307          * For div by zero: want -1 in source1 and 1 in source2 -> -1 result */
308         cond1 = tcg_temp_new();
309         cond2 = tcg_temp_new();
310         zeroreg = tcg_const_tl(0);
311         resultopt1 = tcg_temp_new();
312 
313         tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
314         tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)(~0L));
315         tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
316                             ((target_ulong)1) << (TARGET_LONG_BITS - 1));
317         tcg_gen_and_tl(cond1, cond1, cond2); /* cond1 = overflow */
318         tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, 0); /* cond2 = div 0 */
319         /* if div by zero, set source1 to -1, otherwise don't change */
320         tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond2, zeroreg, source1,
321                 resultopt1);
322         /* if overflow or div by zero, set source2 to 1, else don't change */
323         tcg_gen_or_tl(cond1, cond1, cond2);
324         tcg_gen_movi_tl(resultopt1, (target_ulong)1);
325         tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
326                 resultopt1);
327         tcg_gen_div_tl(source1, source1, source2);
328 
329         tcg_temp_free(cond1);
330         tcg_temp_free(cond2);
331         tcg_temp_free(zeroreg);
332         tcg_temp_free(resultopt1);
333         break;
334 #if defined(TARGET_RISCV64)
335     case OPC_RISC_DIVUW:
336         tcg_gen_ext32u_tl(source1, source1);
337         tcg_gen_ext32u_tl(source2, source2);
338         /* fall through to DIVU */
339 #endif
340     case OPC_RISC_DIVU:
341         cond1 = tcg_temp_new();
342         zeroreg = tcg_const_tl(0);
343         resultopt1 = tcg_temp_new();
344 
345         tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
346         tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
347         tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, source1,
348                 resultopt1);
349         tcg_gen_movi_tl(resultopt1, (target_ulong)1);
350         tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
351                 resultopt1);
352         tcg_gen_divu_tl(source1, source1, source2);
353 
354         tcg_temp_free(cond1);
355         tcg_temp_free(zeroreg);
356         tcg_temp_free(resultopt1);
357         break;
358 #if defined(TARGET_RISCV64)
359     case OPC_RISC_REMW:
360         tcg_gen_ext32s_tl(source1, source1);
361         tcg_gen_ext32s_tl(source2, source2);
362         /* fall through to REM */
363 #endif
364     case OPC_RISC_REM:
365         cond1 = tcg_temp_new();
366         cond2 = tcg_temp_new();
367         zeroreg = tcg_const_tl(0);
368         resultopt1 = tcg_temp_new();
369 
370         tcg_gen_movi_tl(resultopt1, 1L);
371         tcg_gen_setcondi_tl(TCG_COND_EQ, cond2, source2, (target_ulong)-1);
372         tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source1,
373                             (target_ulong)1 << (TARGET_LONG_BITS - 1));
374         tcg_gen_and_tl(cond2, cond1, cond2); /* cond1 = overflow */
375         tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0); /* cond2 = div 0 */
376         /* if overflow or div by zero, set source2 to 1, else don't change */
377         tcg_gen_or_tl(cond2, cond1, cond2);
378         tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond2, zeroreg, source2,
379                 resultopt1);
380         tcg_gen_rem_tl(resultopt1, source1, source2);
381         /* if div by zero, just return the original dividend */
382         tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, resultopt1,
383                 source1);
384 
385         tcg_temp_free(cond1);
386         tcg_temp_free(cond2);
387         tcg_temp_free(zeroreg);
388         tcg_temp_free(resultopt1);
389         break;
390 #if defined(TARGET_RISCV64)
391     case OPC_RISC_REMUW:
392         tcg_gen_ext32u_tl(source1, source1);
393         tcg_gen_ext32u_tl(source2, source2);
394         /* fall through to REMU */
395 #endif
396     case OPC_RISC_REMU:
397         cond1 = tcg_temp_new();
398         zeroreg = tcg_const_tl(0);
399         resultopt1 = tcg_temp_new();
400 
401         tcg_gen_movi_tl(resultopt1, (target_ulong)1);
402         tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
403         tcg_gen_movcond_tl(TCG_COND_EQ, source2, cond1, zeroreg, source2,
404                 resultopt1);
405         tcg_gen_remu_tl(resultopt1, source1, source2);
406         /* if div by zero, just return the original dividend */
407         tcg_gen_movcond_tl(TCG_COND_EQ, source1, cond1, zeroreg, resultopt1,
408                 source1);
409 
410         tcg_temp_free(cond1);
411         tcg_temp_free(zeroreg);
412         tcg_temp_free(resultopt1);
413         break;
414     default:
415         gen_exception_illegal(ctx);
416         return;
417     }
418 
419     if (opc & 0x8) { /* sign extend for W instructions */
420         tcg_gen_ext32s_tl(source1, source1);
421     }
422 
423     gen_set_gpr(rd, source1);
424     tcg_temp_free(source1);
425     tcg_temp_free(source2);
426 }
427 
428 static void gen_arith_imm(DisasContext *ctx, uint32_t opc, int rd,
429         int rs1, target_long imm)
430 {
431     TCGv source1 = tcg_temp_new();
432     int shift_len = TARGET_LONG_BITS;
433     int shift_a;
434 
435     gen_get_gpr(source1, rs1);
436 
437     switch (opc) {
438     case OPC_RISC_ADDI:
439 #if defined(TARGET_RISCV64)
440     case OPC_RISC_ADDIW:
441 #endif
442         tcg_gen_addi_tl(source1, source1, imm);
443         break;
444     case OPC_RISC_SLTI:
445         tcg_gen_setcondi_tl(TCG_COND_LT, source1, source1, imm);
446         break;
447     case OPC_RISC_SLTIU:
448         tcg_gen_setcondi_tl(TCG_COND_LTU, source1, source1, imm);
449         break;
450     case OPC_RISC_XORI:
451         tcg_gen_xori_tl(source1, source1, imm);
452         break;
453     case OPC_RISC_ORI:
454         tcg_gen_ori_tl(source1, source1, imm);
455         break;
456     case OPC_RISC_ANDI:
457         tcg_gen_andi_tl(source1, source1, imm);
458         break;
459 #if defined(TARGET_RISCV64)
460     case OPC_RISC_SLLIW:
461         shift_len = 32;
462         /* FALLTHRU */
463 #endif
464     case OPC_RISC_SLLI:
465         if (imm >= shift_len) {
466             goto do_illegal;
467         }
468         tcg_gen_shli_tl(source1, source1, imm);
469         break;
470 #if defined(TARGET_RISCV64)
471     case OPC_RISC_SHIFT_RIGHT_IW:
472         shift_len = 32;
473         /* FALLTHRU */
474 #endif
475     case OPC_RISC_SHIFT_RIGHT_I:
476         /* differentiate on IMM */
477         shift_a = imm & 0x400;
478         imm &= 0x3ff;
479         if (imm >= shift_len) {
480             goto do_illegal;
481         }
482         if (imm != 0) {
483             if (shift_a) {
484                 /* SRAI[W] */
485                 tcg_gen_sextract_tl(source1, source1, imm, shift_len - imm);
486             } else {
487                 /* SRLI[W] */
488                 tcg_gen_extract_tl(source1, source1, imm, shift_len - imm);
489             }
490             /* No further sign-extension needed for W instructions.  */
491             opc &= ~0x8;
492         }
493         break;
494     default:
495     do_illegal:
496         gen_exception_illegal(ctx);
497         return;
498     }
499 
500     if (opc & 0x8) { /* sign-extend for W instructions */
501         tcg_gen_ext32s_tl(source1, source1);
502     }
503 
504     gen_set_gpr(rd, source1);
505     tcg_temp_free(source1);
506 }
507 
508 static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
509                     target_ulong imm)
510 {
511     target_ulong next_pc;
512 
513     /* check misaligned: */
514     next_pc = ctx->base.pc_next + imm;
515     if (!riscv_has_ext(env, RVC)) {
516         if ((next_pc & 0x3) != 0) {
517             gen_exception_inst_addr_mis(ctx);
518             return;
519         }
520     }
521     if (rd != 0) {
522         tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
523     }
524 
525     gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
526     ctx->base.is_jmp = DISAS_NORETURN;
527 }
528 
529 static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
530                      int rd, int rs1, target_long imm)
531 {
532     /* no chaining with JALR */
533     TCGLabel *misaligned = NULL;
534     TCGv t0 = tcg_temp_new();
535 
536     switch (opc) {
537     case OPC_RISC_JALR:
538         gen_get_gpr(cpu_pc, rs1);
539         tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
540         tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
541 
542         if (!riscv_has_ext(env, RVC)) {
543             misaligned = gen_new_label();
544             tcg_gen_andi_tl(t0, cpu_pc, 0x2);
545             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
546         }
547 
548         if (rd != 0) {
549             tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
550         }
551         tcg_gen_lookup_and_goto_ptr();
552 
553         if (misaligned) {
554             gen_set_label(misaligned);
555             gen_exception_inst_addr_mis(ctx);
556         }
557         ctx->base.is_jmp = DISAS_NORETURN;
558         break;
559 
560     default:
561         gen_exception_illegal(ctx);
562         break;
563     }
564     tcg_temp_free(t0);
565 }
566 
567 static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
568                        int rs1, int rs2, target_long bimm)
569 {
570     TCGLabel *l = gen_new_label();
571     TCGv source1, source2;
572     source1 = tcg_temp_new();
573     source2 = tcg_temp_new();
574     gen_get_gpr(source1, rs1);
575     gen_get_gpr(source2, rs2);
576 
577     switch (opc) {
578     case OPC_RISC_BEQ:
579         tcg_gen_brcond_tl(TCG_COND_EQ, source1, source2, l);
580         break;
581     case OPC_RISC_BNE:
582         tcg_gen_brcond_tl(TCG_COND_NE, source1, source2, l);
583         break;
584     case OPC_RISC_BLT:
585         tcg_gen_brcond_tl(TCG_COND_LT, source1, source2, l);
586         break;
587     case OPC_RISC_BGE:
588         tcg_gen_brcond_tl(TCG_COND_GE, source1, source2, l);
589         break;
590     case OPC_RISC_BLTU:
591         tcg_gen_brcond_tl(TCG_COND_LTU, source1, source2, l);
592         break;
593     case OPC_RISC_BGEU:
594         tcg_gen_brcond_tl(TCG_COND_GEU, source1, source2, l);
595         break;
596     default:
597         gen_exception_illegal(ctx);
598         return;
599     }
600     tcg_temp_free(source1);
601     tcg_temp_free(source2);
602 
603     gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
604     gen_set_label(l); /* branch taken */
605     if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
606         /* misaligned */
607         gen_exception_inst_addr_mis(ctx);
608     } else {
609         gen_goto_tb(ctx, 0, ctx->base.pc_next + bimm);
610     }
611     ctx->base.is_jmp = DISAS_NORETURN;
612 }
613 
614 static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
615         target_long imm)
616 {
617     TCGv t0 = tcg_temp_new();
618     TCGv t1 = tcg_temp_new();
619     gen_get_gpr(t0, rs1);
620     tcg_gen_addi_tl(t0, t0, imm);
621     int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
622 
623     if (memop < 0) {
624         gen_exception_illegal(ctx);
625         return;
626     }
627 
628     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
629     gen_set_gpr(rd, t1);
630     tcg_temp_free(t0);
631     tcg_temp_free(t1);
632 }
633 
634 static void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
635         target_long imm)
636 {
637     TCGv t0 = tcg_temp_new();
638     TCGv dat = tcg_temp_new();
639     gen_get_gpr(t0, rs1);
640     tcg_gen_addi_tl(t0, t0, imm);
641     gen_get_gpr(dat, rs2);
642     int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
643 
644     if (memop < 0) {
645         gen_exception_illegal(ctx);
646         return;
647     }
648 
649     tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
650     tcg_temp_free(t0);
651     tcg_temp_free(dat);
652 }
653 
654 static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
655         int rs1, target_long imm)
656 {
657     TCGv t0;
658 
659     if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
660         gen_exception_illegal(ctx);
661         return;
662     }
663 
664     t0 = tcg_temp_new();
665     gen_get_gpr(t0, rs1);
666     tcg_gen_addi_tl(t0, t0, imm);
667 
668     switch (opc) {
669     case OPC_RISC_FLW:
670         tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
671         /* RISC-V requires NaN-boxing of narrower width floating point values */
672         tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xffffffff00000000ULL);
673         break;
674     case OPC_RISC_FLD:
675         tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
676         break;
677     default:
678         gen_exception_illegal(ctx);
679         break;
680     }
681     tcg_temp_free(t0);
682 }
683 
684 static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
685         int rs2, target_long imm)
686 {
687     TCGv t0;
688 
689     if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
690         gen_exception_illegal(ctx);
691         return;
692     }
693 
694     t0 = tcg_temp_new();
695     gen_get_gpr(t0, rs1);
696     tcg_gen_addi_tl(t0, t0, imm);
697 
698     switch (opc) {
699     case OPC_RISC_FSW:
700         tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
701         break;
702     case OPC_RISC_FSD:
703         tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
704         break;
705     default:
706         gen_exception_illegal(ctx);
707         break;
708     }
709 
710     tcg_temp_free(t0);
711 }
712 
713 static void gen_atomic(DisasContext *ctx, uint32_t opc,
714                       int rd, int rs1, int rs2)
715 {
716     TCGv src1, src2, dat;
717     TCGLabel *l1, *l2;
718     TCGMemOp mop;
719     bool aq, rl;
720 
721     /* Extract the size of the atomic operation.  */
722     switch (extract32(opc, 12, 3)) {
723     case 2: /* 32-bit */
724         mop = MO_ALIGN | MO_TESL;
725         break;
726 #if defined(TARGET_RISCV64)
727     case 3: /* 64-bit */
728         mop = MO_ALIGN | MO_TEQ;
729         break;
730 #endif
731     default:
732         gen_exception_illegal(ctx);
733         return;
734     }
735     rl = extract32(opc, 25, 1);
736     aq = extract32(opc, 26, 1);
737 
738     src1 = tcg_temp_new();
739     src2 = tcg_temp_new();
740 
741     switch (MASK_OP_ATOMIC_NO_AQ_RL_SZ(opc)) {
742     case OPC_RISC_LR:
743         /* Put addr in load_res, data in load_val.  */
744         gen_get_gpr(src1, rs1);
745         if (rl) {
746             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
747         }
748         tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
749         if (aq) {
750             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
751         }
752         tcg_gen_mov_tl(load_res, src1);
753         gen_set_gpr(rd, load_val);
754         break;
755 
756     case OPC_RISC_SC:
757         l1 = gen_new_label();
758         l2 = gen_new_label();
759         dat = tcg_temp_new();
760 
761         gen_get_gpr(src1, rs1);
762         tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
763 
764         gen_get_gpr(src2, rs2);
765         /* Note that the TCG atomic primitives are SC,
766            so we can ignore AQ/RL along this path.  */
767         tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
768                                   ctx->mem_idx, mop);
769         tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
770         gen_set_gpr(rd, dat);
771         tcg_gen_br(l2);
772 
773         gen_set_label(l1);
774         /* Address comparion failure.  However, we still need to
775            provide the memory barrier implied by AQ/RL.  */
776         tcg_gen_mb(TCG_MO_ALL + aq * TCG_BAR_LDAQ + rl * TCG_BAR_STRL);
777         tcg_gen_movi_tl(dat, 1);
778         gen_set_gpr(rd, dat);
779 
780         gen_set_label(l2);
781         tcg_temp_free(dat);
782         break;
783 
784     case OPC_RISC_AMOSWAP:
785         /* Note that the TCG atomic primitives are SC,
786            so we can ignore AQ/RL along this path.  */
787         gen_get_gpr(src1, rs1);
788         gen_get_gpr(src2, rs2);
789         tcg_gen_atomic_xchg_tl(src2, src1, src2, ctx->mem_idx, mop);
790         gen_set_gpr(rd, src2);
791         break;
792     case OPC_RISC_AMOADD:
793         gen_get_gpr(src1, rs1);
794         gen_get_gpr(src2, rs2);
795         tcg_gen_atomic_fetch_add_tl(src2, src1, src2, ctx->mem_idx, mop);
796         gen_set_gpr(rd, src2);
797         break;
798     case OPC_RISC_AMOXOR:
799         gen_get_gpr(src1, rs1);
800         gen_get_gpr(src2, rs2);
801         tcg_gen_atomic_fetch_xor_tl(src2, src1, src2, ctx->mem_idx, mop);
802         gen_set_gpr(rd, src2);
803         break;
804     case OPC_RISC_AMOAND:
805         gen_get_gpr(src1, rs1);
806         gen_get_gpr(src2, rs2);
807         tcg_gen_atomic_fetch_and_tl(src2, src1, src2, ctx->mem_idx, mop);
808         gen_set_gpr(rd, src2);
809         break;
810     case OPC_RISC_AMOOR:
811         gen_get_gpr(src1, rs1);
812         gen_get_gpr(src2, rs2);
813         tcg_gen_atomic_fetch_or_tl(src2, src1, src2, ctx->mem_idx, mop);
814         gen_set_gpr(rd, src2);
815         break;
816     case OPC_RISC_AMOMIN:
817         gen_get_gpr(src1, rs1);
818         gen_get_gpr(src2, rs2);
819         tcg_gen_atomic_fetch_smin_tl(src2, src1, src2, ctx->mem_idx, mop);
820         gen_set_gpr(rd, src2);
821         break;
822     case OPC_RISC_AMOMAX:
823         gen_get_gpr(src1, rs1);
824         gen_get_gpr(src2, rs2);
825         tcg_gen_atomic_fetch_smax_tl(src2, src1, src2, ctx->mem_idx, mop);
826         gen_set_gpr(rd, src2);
827         break;
828     case OPC_RISC_AMOMINU:
829         gen_get_gpr(src1, rs1);
830         gen_get_gpr(src2, rs2);
831         tcg_gen_atomic_fetch_umin_tl(src2, src1, src2, ctx->mem_idx, mop);
832         gen_set_gpr(rd, src2);
833         break;
834     case OPC_RISC_AMOMAXU:
835         gen_get_gpr(src1, rs1);
836         gen_get_gpr(src2, rs2);
837         tcg_gen_atomic_fetch_umax_tl(src2, src1, src2, ctx->mem_idx, mop);
838         gen_set_gpr(rd, src2);
839         break;
840 
841     default:
842         gen_exception_illegal(ctx);
843         break;
844     }
845 
846     tcg_temp_free(src1);
847     tcg_temp_free(src2);
848 }
849 
850 static void gen_set_rm(DisasContext *ctx, int rm)
851 {
852     TCGv_i32 t0;
853 
854     if (ctx->frm == rm) {
855         return;
856     }
857     ctx->frm = rm;
858     t0 = tcg_const_i32(rm);
859     gen_helper_set_rounding_mode(cpu_env, t0);
860     tcg_temp_free_i32(t0);
861 }
862 
863 static void gen_fp_fmadd(DisasContext *ctx, uint32_t opc, int rd,
864                          int rs1, int rs2, int rs3, int rm)
865 {
866     switch (opc) {
867     case OPC_RISC_FMADD_S:
868         gen_set_rm(ctx, rm);
869         gen_helper_fmadd_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
870                            cpu_fpr[rs2], cpu_fpr[rs3]);
871         break;
872     case OPC_RISC_FMADD_D:
873         gen_set_rm(ctx, rm);
874         gen_helper_fmadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
875                            cpu_fpr[rs2], cpu_fpr[rs3]);
876         break;
877     default:
878         gen_exception_illegal(ctx);
879         break;
880     }
881 }
882 
883 static void gen_fp_fmsub(DisasContext *ctx, uint32_t opc, int rd,
884                          int rs1, int rs2, int rs3, int rm)
885 {
886     switch (opc) {
887     case OPC_RISC_FMSUB_S:
888         gen_set_rm(ctx, rm);
889         gen_helper_fmsub_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
890                            cpu_fpr[rs2], cpu_fpr[rs3]);
891         break;
892     case OPC_RISC_FMSUB_D:
893         gen_set_rm(ctx, rm);
894         gen_helper_fmsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
895                            cpu_fpr[rs2], cpu_fpr[rs3]);
896         break;
897     default:
898         gen_exception_illegal(ctx);
899         break;
900     }
901 }
902 
903 static void gen_fp_fnmsub(DisasContext *ctx, uint32_t opc, int rd,
904                           int rs1, int rs2, int rs3, int rm)
905 {
906     switch (opc) {
907     case OPC_RISC_FNMSUB_S:
908         gen_set_rm(ctx, rm);
909         gen_helper_fnmsub_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
910                             cpu_fpr[rs2], cpu_fpr[rs3]);
911         break;
912     case OPC_RISC_FNMSUB_D:
913         gen_set_rm(ctx, rm);
914         gen_helper_fnmsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
915                             cpu_fpr[rs2], cpu_fpr[rs3]);
916         break;
917     default:
918         gen_exception_illegal(ctx);
919         break;
920     }
921 }
922 
923 static void gen_fp_fnmadd(DisasContext *ctx, uint32_t opc, int rd,
924                           int rs1, int rs2, int rs3, int rm)
925 {
926     switch (opc) {
927     case OPC_RISC_FNMADD_S:
928         gen_set_rm(ctx, rm);
929         gen_helper_fnmadd_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
930                             cpu_fpr[rs2], cpu_fpr[rs3]);
931         break;
932     case OPC_RISC_FNMADD_D:
933         gen_set_rm(ctx, rm);
934         gen_helper_fnmadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1],
935                             cpu_fpr[rs2], cpu_fpr[rs3]);
936         break;
937     default:
938         gen_exception_illegal(ctx);
939         break;
940     }
941 }
942 
943 static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
944                          int rs1, int rs2, int rm)
945 {
946     TCGv t0 = NULL;
947 
948     if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
949         goto do_illegal;
950     }
951 
952     switch (opc) {
953     case OPC_RISC_FADD_S:
954         gen_set_rm(ctx, rm);
955         gen_helper_fadd_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
956         break;
957     case OPC_RISC_FSUB_S:
958         gen_set_rm(ctx, rm);
959         gen_helper_fsub_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
960         break;
961     case OPC_RISC_FMUL_S:
962         gen_set_rm(ctx, rm);
963         gen_helper_fmul_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
964         break;
965     case OPC_RISC_FDIV_S:
966         gen_set_rm(ctx, rm);
967         gen_helper_fdiv_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
968         break;
969     case OPC_RISC_FSQRT_S:
970         gen_set_rm(ctx, rm);
971         gen_helper_fsqrt_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
972         break;
973     case OPC_RISC_FSGNJ_S:
974         gen_fsgnj(ctx, rd, rs1, rs2, rm, INT32_MIN);
975         break;
976 
977     case OPC_RISC_FMIN_S:
978         /* also handles: OPC_RISC_FMAX_S */
979         switch (rm) {
980         case 0x0:
981             gen_helper_fmin_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
982             break;
983         case 0x1:
984             gen_helper_fmax_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
985             break;
986         default:
987             goto do_illegal;
988         }
989         break;
990 
991     case OPC_RISC_FEQ_S:
992         /* also handles: OPC_RISC_FLT_S, OPC_RISC_FLE_S */
993         t0 = tcg_temp_new();
994         switch (rm) {
995         case 0x0:
996             gen_helper_fle_s(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
997             break;
998         case 0x1:
999             gen_helper_flt_s(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1000             break;
1001         case 0x2:
1002             gen_helper_feq_s(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1003             break;
1004         default:
1005             goto do_illegal;
1006         }
1007         gen_set_gpr(rd, t0);
1008         tcg_temp_free(t0);
1009         break;
1010 
1011     case OPC_RISC_FCVT_W_S:
1012         /* also OPC_RISC_FCVT_WU_S, OPC_RISC_FCVT_L_S, OPC_RISC_FCVT_LU_S */
1013         t0 = tcg_temp_new();
1014         switch (rs2) {
1015         case 0: /* FCVT_W_S */
1016             gen_set_rm(ctx, rm);
1017             gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[rs1]);
1018             break;
1019         case 1: /* FCVT_WU_S */
1020             gen_set_rm(ctx, rm);
1021             gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[rs1]);
1022             break;
1023 #if defined(TARGET_RISCV64)
1024         case 2: /* FCVT_L_S */
1025             gen_set_rm(ctx, rm);
1026             gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[rs1]);
1027             break;
1028         case 3: /* FCVT_LU_S */
1029             gen_set_rm(ctx, rm);
1030             gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[rs1]);
1031             break;
1032 #endif
1033         default:
1034             goto do_illegal;
1035         }
1036         gen_set_gpr(rd, t0);
1037         tcg_temp_free(t0);
1038         break;
1039 
1040     case OPC_RISC_FCVT_S_W:
1041         /* also OPC_RISC_FCVT_S_WU, OPC_RISC_FCVT_S_L, OPC_RISC_FCVT_S_LU */
1042         t0 = tcg_temp_new();
1043         gen_get_gpr(t0, rs1);
1044         switch (rs2) {
1045         case 0: /* FCVT_S_W */
1046             gen_set_rm(ctx, rm);
1047             gen_helper_fcvt_s_w(cpu_fpr[rd], cpu_env, t0);
1048             break;
1049         case 1: /* FCVT_S_WU */
1050             gen_set_rm(ctx, rm);
1051             gen_helper_fcvt_s_wu(cpu_fpr[rd], cpu_env, t0);
1052             break;
1053 #if defined(TARGET_RISCV64)
1054         case 2: /* FCVT_S_L */
1055             gen_set_rm(ctx, rm);
1056             gen_helper_fcvt_s_l(cpu_fpr[rd], cpu_env, t0);
1057             break;
1058         case 3: /* FCVT_S_LU */
1059             gen_set_rm(ctx, rm);
1060             gen_helper_fcvt_s_lu(cpu_fpr[rd], cpu_env, t0);
1061             break;
1062 #endif
1063         default:
1064             goto do_illegal;
1065         }
1066         tcg_temp_free(t0);
1067         break;
1068 
1069     case OPC_RISC_FMV_X_S:
1070         /* also OPC_RISC_FCLASS_S */
1071         t0 = tcg_temp_new();
1072         switch (rm) {
1073         case 0: /* FMV */
1074 #if defined(TARGET_RISCV64)
1075             tcg_gen_ext32s_tl(t0, cpu_fpr[rs1]);
1076 #else
1077             tcg_gen_extrl_i64_i32(t0, cpu_fpr[rs1]);
1078 #endif
1079             break;
1080         case 1:
1081             gen_helper_fclass_s(t0, cpu_fpr[rs1]);
1082             break;
1083         default:
1084             goto do_illegal;
1085         }
1086         gen_set_gpr(rd, t0);
1087         tcg_temp_free(t0);
1088         break;
1089 
1090     case OPC_RISC_FMV_S_X:
1091         t0 = tcg_temp_new();
1092         gen_get_gpr(t0, rs1);
1093 #if defined(TARGET_RISCV64)
1094         tcg_gen_mov_i64(cpu_fpr[rd], t0);
1095 #else
1096         tcg_gen_extu_i32_i64(cpu_fpr[rd], t0);
1097 #endif
1098         tcg_temp_free(t0);
1099         break;
1100 
1101     /* double */
1102     case OPC_RISC_FADD_D:
1103         gen_set_rm(ctx, rm);
1104         gen_helper_fadd_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1105         break;
1106     case OPC_RISC_FSUB_D:
1107         gen_set_rm(ctx, rm);
1108         gen_helper_fsub_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1109         break;
1110     case OPC_RISC_FMUL_D:
1111         gen_set_rm(ctx, rm);
1112         gen_helper_fmul_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1113         break;
1114     case OPC_RISC_FDIV_D:
1115         gen_set_rm(ctx, rm);
1116         gen_helper_fdiv_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1117         break;
1118     case OPC_RISC_FSQRT_D:
1119         gen_set_rm(ctx, rm);
1120         gen_helper_fsqrt_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
1121         break;
1122     case OPC_RISC_FSGNJ_D:
1123         gen_fsgnj(ctx, rd, rs1, rs2, rm, INT64_MIN);
1124         break;
1125 
1126     case OPC_RISC_FMIN_D:
1127         /* also OPC_RISC_FMAX_D */
1128         switch (rm) {
1129         case 0:
1130             gen_helper_fmin_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1131             break;
1132         case 1:
1133             gen_helper_fmax_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1134             break;
1135         default:
1136             goto do_illegal;
1137         }
1138         break;
1139 
1140     case OPC_RISC_FCVT_S_D:
1141         switch (rs2) {
1142         case 1:
1143             gen_set_rm(ctx, rm);
1144             gen_helper_fcvt_s_d(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
1145             break;
1146         default:
1147             goto do_illegal;
1148         }
1149         break;
1150 
1151     case OPC_RISC_FCVT_D_S:
1152         switch (rs2) {
1153         case 0:
1154             gen_set_rm(ctx, rm);
1155             gen_helper_fcvt_d_s(cpu_fpr[rd], cpu_env, cpu_fpr[rs1]);
1156             break;
1157         default:
1158             goto do_illegal;
1159         }
1160         break;
1161 
1162     case OPC_RISC_FEQ_D:
1163         /* also OPC_RISC_FLT_D, OPC_RISC_FLE_D */
1164         t0 = tcg_temp_new();
1165         switch (rm) {
1166         case 0:
1167             gen_helper_fle_d(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1168             break;
1169         case 1:
1170             gen_helper_flt_d(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1171             break;
1172         case 2:
1173             gen_helper_feq_d(t0, cpu_env, cpu_fpr[rs1], cpu_fpr[rs2]);
1174             break;
1175         default:
1176             goto do_illegal;
1177         }
1178         gen_set_gpr(rd, t0);
1179         tcg_temp_free(t0);
1180         break;
1181 
1182     case OPC_RISC_FCVT_W_D:
1183         /* also OPC_RISC_FCVT_WU_D, OPC_RISC_FCVT_L_D, OPC_RISC_FCVT_LU_D */
1184         t0 = tcg_temp_new();
1185         switch (rs2) {
1186         case 0:
1187             gen_set_rm(ctx, rm);
1188             gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[rs1]);
1189             break;
1190         case 1:
1191             gen_set_rm(ctx, rm);
1192             gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[rs1]);
1193             break;
1194 #if defined(TARGET_RISCV64)
1195         case 2:
1196             gen_set_rm(ctx, rm);
1197             gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[rs1]);
1198             break;
1199         case 3:
1200             gen_set_rm(ctx, rm);
1201             gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[rs1]);
1202             break;
1203 #endif
1204         default:
1205             goto do_illegal;
1206         }
1207         gen_set_gpr(rd, t0);
1208         tcg_temp_free(t0);
1209         break;
1210 
1211     case OPC_RISC_FCVT_D_W:
1212         /* also OPC_RISC_FCVT_D_WU, OPC_RISC_FCVT_D_L, OPC_RISC_FCVT_D_LU */
1213         t0 = tcg_temp_new();
1214         gen_get_gpr(t0, rs1);
1215         switch (rs2) {
1216         case 0:
1217             gen_set_rm(ctx, rm);
1218             gen_helper_fcvt_d_w(cpu_fpr[rd], cpu_env, t0);
1219             break;
1220         case 1:
1221             gen_set_rm(ctx, rm);
1222             gen_helper_fcvt_d_wu(cpu_fpr[rd], cpu_env, t0);
1223             break;
1224 #if defined(TARGET_RISCV64)
1225         case 2:
1226             gen_set_rm(ctx, rm);
1227             gen_helper_fcvt_d_l(cpu_fpr[rd], cpu_env, t0);
1228             break;
1229         case 3:
1230             gen_set_rm(ctx, rm);
1231             gen_helper_fcvt_d_lu(cpu_fpr[rd], cpu_env, t0);
1232             break;
1233 #endif
1234         default:
1235             goto do_illegal;
1236         }
1237         tcg_temp_free(t0);
1238         break;
1239 
1240     case OPC_RISC_FMV_X_D:
1241         /* also OPC_RISC_FCLASS_D */
1242         switch (rm) {
1243 #if defined(TARGET_RISCV64)
1244         case 0: /* FMV */
1245             gen_set_gpr(rd, cpu_fpr[rs1]);
1246             break;
1247 #endif
1248         case 1:
1249             t0 = tcg_temp_new();
1250             gen_helper_fclass_d(t0, cpu_fpr[rs1]);
1251             gen_set_gpr(rd, t0);
1252             tcg_temp_free(t0);
1253             break;
1254         default:
1255             goto do_illegal;
1256         }
1257         break;
1258 
1259 #if defined(TARGET_RISCV64)
1260     case OPC_RISC_FMV_D_X:
1261         t0 = tcg_temp_new();
1262         gen_get_gpr(t0, rs1);
1263         tcg_gen_mov_tl(cpu_fpr[rd], t0);
1264         tcg_temp_free(t0);
1265         break;
1266 #endif
1267 
1268     default:
1269     do_illegal:
1270         if (t0) {
1271             tcg_temp_free(t0);
1272         }
1273         gen_exception_illegal(ctx);
1274         break;
1275     }
1276 }
1277 
1278 static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
1279                       int rd, int rs1, int csr)
1280 {
1281     TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
1282     source1 = tcg_temp_new();
1283     csr_store = tcg_temp_new();
1284     dest = tcg_temp_new();
1285     rs1_pass = tcg_temp_new();
1286     imm_rs1 = tcg_temp_new();
1287     gen_get_gpr(source1, rs1);
1288     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
1289     tcg_gen_movi_tl(rs1_pass, rs1);
1290     tcg_gen_movi_tl(csr_store, csr); /* copy into temp reg to feed to helper */
1291 
1292 #ifndef CONFIG_USER_ONLY
1293     /* Extract funct7 value and check whether it matches SFENCE.VMA */
1294     if ((opc == OPC_RISC_ECALL) && ((csr >> 5) == 9)) {
1295         /* sfence.vma */
1296         /* TODO: handle ASID specific fences */
1297         gen_helper_tlb_flush(cpu_env);
1298         return;
1299     }
1300 #endif
1301 
1302     switch (opc) {
1303     case OPC_RISC_ECALL:
1304         switch (csr) {
1305         case 0x0: /* ECALL */
1306             /* always generates U-level ECALL, fixed in do_interrupt handler */
1307             generate_exception(ctx, RISCV_EXCP_U_ECALL);
1308             tcg_gen_exit_tb(NULL, 0); /* no chaining */
1309             ctx->base.is_jmp = DISAS_NORETURN;
1310             break;
1311         case 0x1: /* EBREAK */
1312             generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
1313             tcg_gen_exit_tb(NULL, 0); /* no chaining */
1314             ctx->base.is_jmp = DISAS_NORETURN;
1315             break;
1316 #ifndef CONFIG_USER_ONLY
1317         case 0x002: /* URET */
1318             gen_exception_illegal(ctx);
1319             break;
1320         case 0x102: /* SRET */
1321             if (riscv_has_ext(env, RVS)) {
1322                 gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
1323                 tcg_gen_exit_tb(NULL, 0); /* no chaining */
1324                 ctx->base.is_jmp = DISAS_NORETURN;
1325             } else {
1326                 gen_exception_illegal(ctx);
1327             }
1328             break;
1329         case 0x202: /* HRET */
1330             gen_exception_illegal(ctx);
1331             break;
1332         case 0x302: /* MRET */
1333             gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
1334             tcg_gen_exit_tb(NULL, 0); /* no chaining */
1335             ctx->base.is_jmp = DISAS_NORETURN;
1336             break;
1337         case 0x7b2: /* DRET */
1338             gen_exception_illegal(ctx);
1339             break;
1340         case 0x105: /* WFI */
1341             tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
1342             gen_helper_wfi(cpu_env);
1343             break;
1344         case 0x104: /* SFENCE.VM */
1345             gen_helper_tlb_flush(cpu_env);
1346             break;
1347 #endif
1348         default:
1349             gen_exception_illegal(ctx);
1350             break;
1351         }
1352         break;
1353     default:
1354         tcg_gen_movi_tl(imm_rs1, rs1);
1355         gen_io_start();
1356         switch (opc) {
1357         case OPC_RISC_CSRRW:
1358             gen_helper_csrrw(dest, cpu_env, source1, csr_store);
1359             break;
1360         case OPC_RISC_CSRRS:
1361             gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
1362             break;
1363         case OPC_RISC_CSRRC:
1364             gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
1365             break;
1366         case OPC_RISC_CSRRWI:
1367             gen_helper_csrrw(dest, cpu_env, imm_rs1, csr_store);
1368             break;
1369         case OPC_RISC_CSRRSI:
1370             gen_helper_csrrs(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
1371             break;
1372         case OPC_RISC_CSRRCI:
1373             gen_helper_csrrc(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
1374             break;
1375         default:
1376             gen_exception_illegal(ctx);
1377             return;
1378         }
1379         gen_io_end();
1380         gen_set_gpr(rd, dest);
1381         /* end tb since we may be changing priv modes, to get mmu_index right */
1382         tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
1383         tcg_gen_exit_tb(NULL, 0); /* no chaining */
1384         ctx->base.is_jmp = DISAS_NORETURN;
1385         break;
1386     }
1387     tcg_temp_free(source1);
1388     tcg_temp_free(csr_store);
1389     tcg_temp_free(dest);
1390     tcg_temp_free(rs1_pass);
1391     tcg_temp_free(imm_rs1);
1392 }
1393 
1394 static void decode_RV32_64C0(DisasContext *ctx)
1395 {
1396     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
1397     uint8_t rd_rs2 = GET_C_RS2S(ctx->opcode);
1398     uint8_t rs1s = GET_C_RS1S(ctx->opcode);
1399 
1400     switch (funct3) {
1401     case 0:
1402         /* illegal */
1403         if (ctx->opcode == 0) {
1404             gen_exception_illegal(ctx);
1405         } else {
1406             /* C.ADDI4SPN -> addi rd', x2, zimm[9:2]*/
1407             gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs2, 2,
1408                           GET_C_ADDI4SPN_IMM(ctx->opcode));
1409         }
1410         break;
1411     case 1:
1412         /* C.FLD -> fld rd', offset[7:3](rs1')*/
1413         gen_fp_load(ctx, OPC_RISC_FLD, rd_rs2, rs1s,
1414                     GET_C_LD_IMM(ctx->opcode));
1415         /* C.LQ(RV128) */
1416         break;
1417     case 2:
1418         /* C.LW -> lw rd', offset[6:2](rs1') */
1419         gen_load(ctx, OPC_RISC_LW, rd_rs2, rs1s,
1420                  GET_C_LW_IMM(ctx->opcode));
1421         break;
1422     case 3:
1423 #if defined(TARGET_RISCV64)
1424         /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
1425         gen_load(ctx, OPC_RISC_LD, rd_rs2, rs1s,
1426                  GET_C_LD_IMM(ctx->opcode));
1427 #else
1428         /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
1429         gen_fp_load(ctx, OPC_RISC_FLW, rd_rs2, rs1s,
1430                     GET_C_LW_IMM(ctx->opcode));
1431 #endif
1432         break;
1433     case 4:
1434         /* reserved */
1435         gen_exception_illegal(ctx);
1436         break;
1437     case 5:
1438         /* C.FSD(RV32/64) -> fsd rs2', offset[7:3](rs1') */
1439         gen_fp_store(ctx, OPC_RISC_FSD, rs1s, rd_rs2,
1440                      GET_C_LD_IMM(ctx->opcode));
1441         /* C.SQ (RV128) */
1442         break;
1443     case 6:
1444         /* C.SW -> sw rs2', offset[6:2](rs1')*/
1445         gen_store(ctx, OPC_RISC_SW, rs1s, rd_rs2,
1446                   GET_C_LW_IMM(ctx->opcode));
1447         break;
1448     case 7:
1449 #if defined(TARGET_RISCV64)
1450         /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
1451         gen_store(ctx, OPC_RISC_SD, rs1s, rd_rs2,
1452                   GET_C_LD_IMM(ctx->opcode));
1453 #else
1454         /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
1455         gen_fp_store(ctx, OPC_RISC_FSW, rs1s, rd_rs2,
1456                      GET_C_LW_IMM(ctx->opcode));
1457 #endif
1458         break;
1459     }
1460 }
1461 
1462 static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
1463 {
1464     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
1465     uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
1466     uint8_t rs1s, rs2s;
1467     uint8_t funct2;
1468 
1469     switch (funct3) {
1470     case 0:
1471         /* C.ADDI -> addi rd, rd, nzimm[5:0] */
1472         gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs1, rd_rs1,
1473                       GET_C_IMM(ctx->opcode));
1474         break;
1475     case 1:
1476 #if defined(TARGET_RISCV64)
1477         /* C.ADDIW (RV64/128) -> addiw rd, rd, imm[5:0]*/
1478         gen_arith_imm(ctx, OPC_RISC_ADDIW, rd_rs1, rd_rs1,
1479                       GET_C_IMM(ctx->opcode));
1480 #else
1481         /* C.JAL(RV32) -> jal x1, offset[11:1] */
1482         gen_jal(env, ctx, 1, GET_C_J_IMM(ctx->opcode));
1483 #endif
1484         break;
1485     case 2:
1486         /* C.LI -> addi rd, x0, imm[5:0]*/
1487         gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs1, 0, GET_C_IMM(ctx->opcode));
1488         break;
1489     case 3:
1490         if (rd_rs1 == 2) {
1491             /* C.ADDI16SP -> addi x2, x2, nzimm[9:4]*/
1492             gen_arith_imm(ctx, OPC_RISC_ADDI, 2, 2,
1493                           GET_C_ADDI16SP_IMM(ctx->opcode));
1494         } else if (rd_rs1 != 0) {
1495             /* C.LUI (rs1/rd =/= {0,2}) -> lui rd, nzimm[17:12]*/
1496             tcg_gen_movi_tl(cpu_gpr[rd_rs1],
1497                             GET_C_IMM(ctx->opcode) << 12);
1498         }
1499         break;
1500     case 4:
1501         funct2 = extract32(ctx->opcode, 10, 2);
1502         rs1s = GET_C_RS1S(ctx->opcode);
1503         switch (funct2) {
1504         case 0: /* C.SRLI(RV32) -> srli rd', rd', shamt[5:0] */
1505             gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, rs1s, rs1s,
1506                                GET_C_ZIMM(ctx->opcode));
1507             /* C.SRLI64(RV128) */
1508             break;
1509         case 1:
1510             /* C.SRAI -> srai rd', rd', shamt[5:0]*/
1511             gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, rs1s, rs1s,
1512                             GET_C_ZIMM(ctx->opcode) | 0x400);
1513             /* C.SRAI64(RV128) */
1514             break;
1515         case 2:
1516             /* C.ANDI -> andi rd', rd', imm[5:0]*/
1517             gen_arith_imm(ctx, OPC_RISC_ANDI, rs1s, rs1s,
1518                           GET_C_IMM(ctx->opcode));
1519             break;
1520         case 3:
1521             funct2 = extract32(ctx->opcode, 5, 2);
1522             rs2s = GET_C_RS2S(ctx->opcode);
1523             switch (funct2) {
1524             case 0:
1525                 /* C.SUB -> sub rd', rd', rs2' */
1526                 if (extract32(ctx->opcode, 12, 1) == 0) {
1527                     gen_arith(ctx, OPC_RISC_SUB, rs1s, rs1s, rs2s);
1528                 }
1529 #if defined(TARGET_RISCV64)
1530                 else {
1531                     gen_arith(ctx, OPC_RISC_SUBW, rs1s, rs1s, rs2s);
1532                 }
1533 #endif
1534                 break;
1535             case 1:
1536                 /* C.XOR -> xor rs1', rs1', rs2' */
1537                 if (extract32(ctx->opcode, 12, 1) == 0) {
1538                     gen_arith(ctx, OPC_RISC_XOR, rs1s, rs1s, rs2s);
1539                 }
1540 #if defined(TARGET_RISCV64)
1541                 else {
1542                     /* C.ADDW (RV64/128) */
1543                     gen_arith(ctx, OPC_RISC_ADDW, rs1s, rs1s, rs2s);
1544                 }
1545 #endif
1546                 break;
1547             case 2:
1548                 /* C.OR -> or rs1', rs1', rs2' */
1549                 gen_arith(ctx, OPC_RISC_OR, rs1s, rs1s, rs2s);
1550                 break;
1551             case 3:
1552                 /* C.AND -> and rs1', rs1', rs2' */
1553                 gen_arith(ctx, OPC_RISC_AND, rs1s, rs1s, rs2s);
1554                 break;
1555             }
1556             break;
1557         }
1558         break;
1559     case 5:
1560         /* C.J -> jal x0, offset[11:1]*/
1561         gen_jal(env, ctx, 0, GET_C_J_IMM(ctx->opcode));
1562         break;
1563     case 6:
1564         /* C.BEQZ -> beq rs1', x0, offset[8:1]*/
1565         rs1s = GET_C_RS1S(ctx->opcode);
1566         gen_branch(env, ctx, OPC_RISC_BEQ, rs1s, 0, GET_C_B_IMM(ctx->opcode));
1567         break;
1568     case 7:
1569         /* C.BNEZ -> bne rs1', x0, offset[8:1]*/
1570         rs1s = GET_C_RS1S(ctx->opcode);
1571         gen_branch(env, ctx, OPC_RISC_BNE, rs1s, 0, GET_C_B_IMM(ctx->opcode));
1572         break;
1573     }
1574 }
1575 
1576 static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
1577 {
1578     uint8_t rd, rs2;
1579     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
1580 
1581 
1582     rd = GET_RD(ctx->opcode);
1583 
1584     switch (funct3) {
1585     case 0: /* C.SLLI -> slli rd, rd, shamt[5:0]
1586                C.SLLI64 -> */
1587         gen_arith_imm(ctx, OPC_RISC_SLLI, rd, rd, GET_C_ZIMM(ctx->opcode));
1588         break;
1589     case 1: /* C.FLDSP(RV32/64DC) -> fld rd, offset[8:3](x2) */
1590         gen_fp_load(ctx, OPC_RISC_FLD, rd, 2, GET_C_LDSP_IMM(ctx->opcode));
1591         break;
1592     case 2: /* C.LWSP -> lw rd, offset[7:2](x2) */
1593         gen_load(ctx, OPC_RISC_LW, rd, 2, GET_C_LWSP_IMM(ctx->opcode));
1594         break;
1595     case 3:
1596 #if defined(TARGET_RISCV64)
1597         /* C.LDSP(RVC64) -> ld rd, offset[8:3](x2) */
1598         gen_load(ctx, OPC_RISC_LD, rd, 2, GET_C_LDSP_IMM(ctx->opcode));
1599 #else
1600         /* C.FLWSP(RV32FC) -> flw rd, offset[7:2](x2) */
1601         gen_fp_load(ctx, OPC_RISC_FLW, rd, 2, GET_C_LWSP_IMM(ctx->opcode));
1602 #endif
1603         break;
1604     case 4:
1605         rs2 = GET_C_RS2(ctx->opcode);
1606 
1607         if (extract32(ctx->opcode, 12, 1) == 0) {
1608             if (rs2 == 0) {
1609                 /* C.JR -> jalr x0, rs1, 0*/
1610                 gen_jalr(env, ctx, OPC_RISC_JALR, 0, rd, 0);
1611             } else {
1612                 /* C.MV -> add rd, x0, rs2 */
1613                 gen_arith(ctx, OPC_RISC_ADD, rd, 0, rs2);
1614             }
1615         } else {
1616             if (rd == 0) {
1617                 /* C.EBREAK -> ebreak*/
1618                 gen_system(env, ctx, OPC_RISC_ECALL, 0, 0, 0x1);
1619             } else {
1620                 if (rs2 == 0) {
1621                     /* C.JALR -> jalr x1, rs1, 0*/
1622                     gen_jalr(env, ctx, OPC_RISC_JALR, 1, rd, 0);
1623                 } else {
1624                     /* C.ADD -> add rd, rd, rs2 */
1625                     gen_arith(ctx, OPC_RISC_ADD, rd, rd, rs2);
1626                 }
1627             }
1628         }
1629         break;
1630     case 5:
1631         /* C.FSDSP -> fsd rs2, offset[8:3](x2)*/
1632         gen_fp_store(ctx, OPC_RISC_FSD, 2, GET_C_RS2(ctx->opcode),
1633                      GET_C_SDSP_IMM(ctx->opcode));
1634         /* C.SQSP */
1635         break;
1636     case 6: /* C.SWSP -> sw rs2, offset[7:2](x2)*/
1637         gen_store(ctx, OPC_RISC_SW, 2, GET_C_RS2(ctx->opcode),
1638                   GET_C_SWSP_IMM(ctx->opcode));
1639         break;
1640     case 7:
1641 #if defined(TARGET_RISCV64)
1642         /* C.SDSP(Rv64/128) -> sd rs2, offset[8:3](x2)*/
1643         gen_store(ctx, OPC_RISC_SD, 2, GET_C_RS2(ctx->opcode),
1644                   GET_C_SDSP_IMM(ctx->opcode));
1645 #else
1646         /* C.FSWSP(RV32) -> fsw rs2, offset[7:2](x2) */
1647         gen_fp_store(ctx, OPC_RISC_FSW, 2, GET_C_RS2(ctx->opcode),
1648                      GET_C_SWSP_IMM(ctx->opcode));
1649 #endif
1650         break;
1651     }
1652 }
1653 
1654 static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
1655 {
1656     uint8_t op = extract32(ctx->opcode, 0, 2);
1657 
1658     switch (op) {
1659     case 0:
1660         decode_RV32_64C0(ctx);
1661         break;
1662     case 1:
1663         decode_RV32_64C1(env, ctx);
1664         break;
1665     case 2:
1666         decode_RV32_64C2(env, ctx);
1667         break;
1668     }
1669 }
1670 
1671 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
1672 {
1673     int rs1;
1674     int rs2;
1675     int rd;
1676     uint32_t op;
1677     target_long imm;
1678 
1679     /* We do not do misaligned address check here: the address should never be
1680      * misaligned at this point. Instructions that set PC must do the check,
1681      * since epc must be the address of the instruction that caused us to
1682      * perform the misaligned instruction fetch */
1683 
1684     op = MASK_OP_MAJOR(ctx->opcode);
1685     rs1 = GET_RS1(ctx->opcode);
1686     rs2 = GET_RS2(ctx->opcode);
1687     rd = GET_RD(ctx->opcode);
1688     imm = GET_IMM(ctx->opcode);
1689 
1690     switch (op) {
1691     case OPC_RISC_LUI:
1692         if (rd == 0) {
1693             break; /* NOP */
1694         }
1695         tcg_gen_movi_tl(cpu_gpr[rd], sextract64(ctx->opcode, 12, 20) << 12);
1696         break;
1697     case OPC_RISC_AUIPC:
1698         if (rd == 0) {
1699             break; /* NOP */
1700         }
1701         tcg_gen_movi_tl(cpu_gpr[rd], (sextract64(ctx->opcode, 12, 20) << 12) +
1702                ctx->base.pc_next);
1703         break;
1704     case OPC_RISC_JAL:
1705         imm = GET_JAL_IMM(ctx->opcode);
1706         gen_jal(env, ctx, rd, imm);
1707         break;
1708     case OPC_RISC_JALR:
1709         gen_jalr(env, ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
1710         break;
1711     case OPC_RISC_BRANCH:
1712         gen_branch(env, ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
1713                    GET_B_IMM(ctx->opcode));
1714         break;
1715     case OPC_RISC_LOAD:
1716         gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
1717         break;
1718     case OPC_RISC_STORE:
1719         gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
1720                   GET_STORE_IMM(ctx->opcode));
1721         break;
1722     case OPC_RISC_ARITH_IMM:
1723 #if defined(TARGET_RISCV64)
1724     case OPC_RISC_ARITH_IMM_W:
1725 #endif
1726         if (rd == 0) {
1727             break; /* NOP */
1728         }
1729         gen_arith_imm(ctx, MASK_OP_ARITH_IMM(ctx->opcode), rd, rs1, imm);
1730         break;
1731     case OPC_RISC_ARITH:
1732 #if defined(TARGET_RISCV64)
1733     case OPC_RISC_ARITH_W:
1734 #endif
1735         if (rd == 0) {
1736             break; /* NOP */
1737         }
1738         gen_arith(ctx, MASK_OP_ARITH(ctx->opcode), rd, rs1, rs2);
1739         break;
1740     case OPC_RISC_FP_LOAD:
1741         gen_fp_load(ctx, MASK_OP_FP_LOAD(ctx->opcode), rd, rs1, imm);
1742         break;
1743     case OPC_RISC_FP_STORE:
1744         gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
1745                      GET_STORE_IMM(ctx->opcode));
1746         break;
1747     case OPC_RISC_ATOMIC:
1748         gen_atomic(ctx, MASK_OP_ATOMIC(ctx->opcode), rd, rs1, rs2);
1749         break;
1750     case OPC_RISC_FMADD:
1751         gen_fp_fmadd(ctx, MASK_OP_FP_FMADD(ctx->opcode), rd, rs1, rs2,
1752                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1753         break;
1754     case OPC_RISC_FMSUB:
1755         gen_fp_fmsub(ctx, MASK_OP_FP_FMSUB(ctx->opcode), rd, rs1, rs2,
1756                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1757         break;
1758     case OPC_RISC_FNMSUB:
1759         gen_fp_fnmsub(ctx, MASK_OP_FP_FNMSUB(ctx->opcode), rd, rs1, rs2,
1760                       GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1761         break;
1762     case OPC_RISC_FNMADD:
1763         gen_fp_fnmadd(ctx, MASK_OP_FP_FNMADD(ctx->opcode), rd, rs1, rs2,
1764                       GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1765         break;
1766     case OPC_RISC_FP_ARITH:
1767         gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
1768                      GET_RM(ctx->opcode));
1769         break;
1770     case OPC_RISC_FENCE:
1771 #ifndef CONFIG_USER_ONLY
1772         if (ctx->opcode & 0x1000) {
1773             /* FENCE_I is a no-op in QEMU,
1774              * however we need to end the translation block */
1775             tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
1776             tcg_gen_exit_tb(NULL, 0);
1777             ctx->base.is_jmp = DISAS_NORETURN;
1778         } else {
1779             /* FENCE is a full memory barrier. */
1780             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1781         }
1782 #endif
1783         break;
1784     case OPC_RISC_SYSTEM:
1785         gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
1786                    (ctx->opcode & 0xFFF00000) >> 20);
1787         break;
1788     default:
1789         gen_exception_illegal(ctx);
1790         break;
1791     }
1792 }
1793 
1794 static void decode_opc(CPURISCVState *env, DisasContext *ctx)
1795 {
1796     /* check for compressed insn */
1797     if (extract32(ctx->opcode, 0, 2) != 3) {
1798         if (!riscv_has_ext(env, RVC)) {
1799             gen_exception_illegal(ctx);
1800         } else {
1801             ctx->pc_succ_insn = ctx->base.pc_next + 2;
1802             decode_RV32_64C(env, ctx);
1803         }
1804     } else {
1805         ctx->pc_succ_insn = ctx->base.pc_next + 4;
1806         decode_RV32_64G(env, ctx);
1807     }
1808 }
1809 
1810 static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
1811 {
1812     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1813 
1814     ctx->pc_succ_insn = ctx->base.pc_first;
1815     ctx->flags = ctx->base.tb->flags;
1816     ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
1817     ctx->frm = -1;  /* unknown rounding mode */
1818 }
1819 
1820 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
1821 {
1822 }
1823 
1824 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1825 {
1826     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1827 
1828     tcg_gen_insn_start(ctx->base.pc_next);
1829 }
1830 
1831 static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
1832                                       const CPUBreakpoint *bp)
1833 {
1834     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1835 
1836     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
1837     ctx->base.is_jmp = DISAS_NORETURN;
1838     gen_exception_debug();
1839     /* The address covered by the breakpoint must be included in
1840        [tb->pc, tb->pc + tb->size) in order to for it to be
1841        properly cleared -- thus we increment the PC here so that
1842        the logic setting tb->size below does the right thing.  */
1843     ctx->base.pc_next += 4;
1844     return true;
1845 }
1846 
1847 
1848 static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1849 {
1850     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1851     CPURISCVState *env = cpu->env_ptr;
1852 
1853     ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
1854     decode_opc(env, ctx);
1855     ctx->base.pc_next = ctx->pc_succ_insn;
1856 
1857     if (ctx->base.is_jmp == DISAS_NEXT) {
1858         target_ulong page_start;
1859 
1860         page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
1861         if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
1862             ctx->base.is_jmp = DISAS_TOO_MANY;
1863         }
1864     }
1865 }
1866 
1867 static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1868 {
1869     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1870 
1871     switch (ctx->base.is_jmp) {
1872     case DISAS_TOO_MANY:
1873         gen_goto_tb(ctx, 0, ctx->base.pc_next);
1874         break;
1875     case DISAS_NORETURN:
1876         break;
1877     default:
1878         g_assert_not_reached();
1879     }
1880 }
1881 
1882 static void riscv_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
1883 {
1884     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
1885     log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
1886 }
1887 
1888 static const TranslatorOps riscv_tr_ops = {
1889     .init_disas_context = riscv_tr_init_disas_context,
1890     .tb_start           = riscv_tr_tb_start,
1891     .insn_start         = riscv_tr_insn_start,
1892     .breakpoint_check   = riscv_tr_breakpoint_check,
1893     .translate_insn     = riscv_tr_translate_insn,
1894     .tb_stop            = riscv_tr_tb_stop,
1895     .disas_log          = riscv_tr_disas_log,
1896 };
1897 
1898 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
1899 {
1900     DisasContext ctx;
1901 
1902     translator_loop(&riscv_tr_ops, &ctx.base, cs, tb);
1903 }
1904 
1905 void riscv_translate_init(void)
1906 {
1907     int i;
1908 
1909     /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
1910     /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
1911     /* registers, unless you specifically block reads/writes to reg 0 */
1912     cpu_gpr[0] = NULL;
1913 
1914     for (i = 1; i < 32; i++) {
1915         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
1916             offsetof(CPURISCVState, gpr[i]), riscv_int_regnames[i]);
1917     }
1918 
1919     for (i = 0; i < 32; i++) {
1920         cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
1921             offsetof(CPURISCVState, fpr[i]), riscv_fpr_regnames[i]);
1922     }
1923 
1924     cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, pc), "pc");
1925     load_res = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_res),
1926                              "load_res");
1927     load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
1928                              "load_val");
1929 }
1930