xref: /qemu/target/riscv/translate.c (revision 9e6bdef2)
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 #if defined(TARGET_RISCV64)
1241     case OPC_RISC_FMV_X_D:
1242         /* also OPC_RISC_FCLASS_D */
1243         switch (rm) {
1244         case 0: /* FMV */
1245             gen_set_gpr(rd, cpu_fpr[rs1]);
1246             break;
1247         case 1:
1248             t0 = tcg_temp_new();
1249             gen_helper_fclass_d(t0, cpu_fpr[rs1]);
1250             gen_set_gpr(rd, t0);
1251             tcg_temp_free(t0);
1252             break;
1253         default:
1254             goto do_illegal;
1255         }
1256         break;
1257 
1258     case OPC_RISC_FMV_D_X:
1259         t0 = tcg_temp_new();
1260         gen_get_gpr(t0, rs1);
1261         tcg_gen_mov_tl(cpu_fpr[rd], t0);
1262         tcg_temp_free(t0);
1263         break;
1264 #endif
1265 
1266     default:
1267     do_illegal:
1268         if (t0) {
1269             tcg_temp_free(t0);
1270         }
1271         gen_exception_illegal(ctx);
1272         break;
1273     }
1274 }
1275 
1276 static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
1277                       int rd, int rs1, int csr)
1278 {
1279     TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
1280     source1 = tcg_temp_new();
1281     csr_store = tcg_temp_new();
1282     dest = tcg_temp_new();
1283     rs1_pass = tcg_temp_new();
1284     imm_rs1 = tcg_temp_new();
1285     gen_get_gpr(source1, rs1);
1286     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
1287     tcg_gen_movi_tl(rs1_pass, rs1);
1288     tcg_gen_movi_tl(csr_store, csr); /* copy into temp reg to feed to helper */
1289 
1290 #ifndef CONFIG_USER_ONLY
1291     /* Extract funct7 value and check whether it matches SFENCE.VMA */
1292     if ((opc == OPC_RISC_ECALL) && ((csr >> 5) == 9)) {
1293         /* sfence.vma */
1294         /* TODO: handle ASID specific fences */
1295         gen_helper_tlb_flush(cpu_env);
1296         return;
1297     }
1298 #endif
1299 
1300     switch (opc) {
1301     case OPC_RISC_ECALL:
1302         switch (csr) {
1303         case 0x0: /* ECALL */
1304             /* always generates U-level ECALL, fixed in do_interrupt handler */
1305             generate_exception(ctx, RISCV_EXCP_U_ECALL);
1306             tcg_gen_exit_tb(NULL, 0); /* no chaining */
1307             ctx->base.is_jmp = DISAS_NORETURN;
1308             break;
1309         case 0x1: /* EBREAK */
1310             generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
1311             tcg_gen_exit_tb(NULL, 0); /* no chaining */
1312             ctx->base.is_jmp = DISAS_NORETURN;
1313             break;
1314 #ifndef CONFIG_USER_ONLY
1315         case 0x002: /* URET */
1316             gen_exception_illegal(ctx);
1317             break;
1318         case 0x102: /* SRET */
1319             if (riscv_has_ext(env, RVS)) {
1320                 gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
1321                 tcg_gen_exit_tb(NULL, 0); /* no chaining */
1322                 ctx->base.is_jmp = DISAS_NORETURN;
1323             } else {
1324                 gen_exception_illegal(ctx);
1325             }
1326             break;
1327         case 0x202: /* HRET */
1328             gen_exception_illegal(ctx);
1329             break;
1330         case 0x302: /* MRET */
1331             gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
1332             tcg_gen_exit_tb(NULL, 0); /* no chaining */
1333             ctx->base.is_jmp = DISAS_NORETURN;
1334             break;
1335         case 0x7b2: /* DRET */
1336             gen_exception_illegal(ctx);
1337             break;
1338         case 0x105: /* WFI */
1339             tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
1340             gen_helper_wfi(cpu_env);
1341             break;
1342         case 0x104: /* SFENCE.VM */
1343             gen_helper_tlb_flush(cpu_env);
1344             break;
1345 #endif
1346         default:
1347             gen_exception_illegal(ctx);
1348             break;
1349         }
1350         break;
1351     default:
1352         tcg_gen_movi_tl(imm_rs1, rs1);
1353         gen_io_start();
1354         switch (opc) {
1355         case OPC_RISC_CSRRW:
1356             gen_helper_csrrw(dest, cpu_env, source1, csr_store);
1357             break;
1358         case OPC_RISC_CSRRS:
1359             gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
1360             break;
1361         case OPC_RISC_CSRRC:
1362             gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
1363             break;
1364         case OPC_RISC_CSRRWI:
1365             gen_helper_csrrw(dest, cpu_env, imm_rs1, csr_store);
1366             break;
1367         case OPC_RISC_CSRRSI:
1368             gen_helper_csrrs(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
1369             break;
1370         case OPC_RISC_CSRRCI:
1371             gen_helper_csrrc(dest, cpu_env, imm_rs1, csr_store, rs1_pass);
1372             break;
1373         default:
1374             gen_exception_illegal(ctx);
1375             return;
1376         }
1377         gen_io_end();
1378         gen_set_gpr(rd, dest);
1379         /* end tb since we may be changing priv modes, to get mmu_index right */
1380         tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
1381         tcg_gen_exit_tb(NULL, 0); /* no chaining */
1382         ctx->base.is_jmp = DISAS_NORETURN;
1383         break;
1384     }
1385     tcg_temp_free(source1);
1386     tcg_temp_free(csr_store);
1387     tcg_temp_free(dest);
1388     tcg_temp_free(rs1_pass);
1389     tcg_temp_free(imm_rs1);
1390 }
1391 
1392 static void decode_RV32_64C0(DisasContext *ctx)
1393 {
1394     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
1395     uint8_t rd_rs2 = GET_C_RS2S(ctx->opcode);
1396     uint8_t rs1s = GET_C_RS1S(ctx->opcode);
1397 
1398     switch (funct3) {
1399     case 0:
1400         /* illegal */
1401         if (ctx->opcode == 0) {
1402             gen_exception_illegal(ctx);
1403         } else {
1404             /* C.ADDI4SPN -> addi rd', x2, zimm[9:2]*/
1405             gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs2, 2,
1406                           GET_C_ADDI4SPN_IMM(ctx->opcode));
1407         }
1408         break;
1409     case 1:
1410         /* C.FLD -> fld rd', offset[7:3](rs1')*/
1411         gen_fp_load(ctx, OPC_RISC_FLD, rd_rs2, rs1s,
1412                     GET_C_LD_IMM(ctx->opcode));
1413         /* C.LQ(RV128) */
1414         break;
1415     case 2:
1416         /* C.LW -> lw rd', offset[6:2](rs1') */
1417         gen_load(ctx, OPC_RISC_LW, rd_rs2, rs1s,
1418                  GET_C_LW_IMM(ctx->opcode));
1419         break;
1420     case 3:
1421 #if defined(TARGET_RISCV64)
1422         /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
1423         gen_load(ctx, OPC_RISC_LD, rd_rs2, rs1s,
1424                  GET_C_LD_IMM(ctx->opcode));
1425 #else
1426         /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
1427         gen_fp_load(ctx, OPC_RISC_FLW, rd_rs2, rs1s,
1428                     GET_C_LW_IMM(ctx->opcode));
1429 #endif
1430         break;
1431     case 4:
1432         /* reserved */
1433         gen_exception_illegal(ctx);
1434         break;
1435     case 5:
1436         /* C.FSD(RV32/64) -> fsd rs2', offset[7:3](rs1') */
1437         gen_fp_store(ctx, OPC_RISC_FSD, rs1s, rd_rs2,
1438                      GET_C_LD_IMM(ctx->opcode));
1439         /* C.SQ (RV128) */
1440         break;
1441     case 6:
1442         /* C.SW -> sw rs2', offset[6:2](rs1')*/
1443         gen_store(ctx, OPC_RISC_SW, rs1s, rd_rs2,
1444                   GET_C_LW_IMM(ctx->opcode));
1445         break;
1446     case 7:
1447 #if defined(TARGET_RISCV64)
1448         /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
1449         gen_store(ctx, OPC_RISC_SD, rs1s, rd_rs2,
1450                   GET_C_LD_IMM(ctx->opcode));
1451 #else
1452         /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
1453         gen_fp_store(ctx, OPC_RISC_FSW, rs1s, rd_rs2,
1454                      GET_C_LW_IMM(ctx->opcode));
1455 #endif
1456         break;
1457     }
1458 }
1459 
1460 static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
1461 {
1462     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
1463     uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
1464     uint8_t rs1s, rs2s;
1465     uint8_t funct2;
1466 
1467     switch (funct3) {
1468     case 0:
1469         /* C.ADDI -> addi rd, rd, nzimm[5:0] */
1470         gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs1, rd_rs1,
1471                       GET_C_IMM(ctx->opcode));
1472         break;
1473     case 1:
1474 #if defined(TARGET_RISCV64)
1475         /* C.ADDIW (RV64/128) -> addiw rd, rd, imm[5:0]*/
1476         gen_arith_imm(ctx, OPC_RISC_ADDIW, rd_rs1, rd_rs1,
1477                       GET_C_IMM(ctx->opcode));
1478 #else
1479         /* C.JAL(RV32) -> jal x1, offset[11:1] */
1480         gen_jal(env, ctx, 1, GET_C_J_IMM(ctx->opcode));
1481 #endif
1482         break;
1483     case 2:
1484         /* C.LI -> addi rd, x0, imm[5:0]*/
1485         gen_arith_imm(ctx, OPC_RISC_ADDI, rd_rs1, 0, GET_C_IMM(ctx->opcode));
1486         break;
1487     case 3:
1488         if (rd_rs1 == 2) {
1489             /* C.ADDI16SP -> addi x2, x2, nzimm[9:4]*/
1490             gen_arith_imm(ctx, OPC_RISC_ADDI, 2, 2,
1491                           GET_C_ADDI16SP_IMM(ctx->opcode));
1492         } else if (rd_rs1 != 0) {
1493             /* C.LUI (rs1/rd =/= {0,2}) -> lui rd, nzimm[17:12]*/
1494             tcg_gen_movi_tl(cpu_gpr[rd_rs1],
1495                             GET_C_IMM(ctx->opcode) << 12);
1496         }
1497         break;
1498     case 4:
1499         funct2 = extract32(ctx->opcode, 10, 2);
1500         rs1s = GET_C_RS1S(ctx->opcode);
1501         switch (funct2) {
1502         case 0: /* C.SRLI(RV32) -> srli rd', rd', shamt[5:0] */
1503             gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, rs1s, rs1s,
1504                                GET_C_ZIMM(ctx->opcode));
1505             /* C.SRLI64(RV128) */
1506             break;
1507         case 1:
1508             /* C.SRAI -> srai rd', rd', shamt[5:0]*/
1509             gen_arith_imm(ctx, OPC_RISC_SHIFT_RIGHT_I, rs1s, rs1s,
1510                             GET_C_ZIMM(ctx->opcode) | 0x400);
1511             /* C.SRAI64(RV128) */
1512             break;
1513         case 2:
1514             /* C.ANDI -> andi rd', rd', imm[5:0]*/
1515             gen_arith_imm(ctx, OPC_RISC_ANDI, rs1s, rs1s,
1516                           GET_C_IMM(ctx->opcode));
1517             break;
1518         case 3:
1519             funct2 = extract32(ctx->opcode, 5, 2);
1520             rs2s = GET_C_RS2S(ctx->opcode);
1521             switch (funct2) {
1522             case 0:
1523                 /* C.SUB -> sub rd', rd', rs2' */
1524                 if (extract32(ctx->opcode, 12, 1) == 0) {
1525                     gen_arith(ctx, OPC_RISC_SUB, rs1s, rs1s, rs2s);
1526                 }
1527 #if defined(TARGET_RISCV64)
1528                 else {
1529                     gen_arith(ctx, OPC_RISC_SUBW, rs1s, rs1s, rs2s);
1530                 }
1531 #endif
1532                 break;
1533             case 1:
1534                 /* C.XOR -> xor rs1', rs1', rs2' */
1535                 if (extract32(ctx->opcode, 12, 1) == 0) {
1536                     gen_arith(ctx, OPC_RISC_XOR, rs1s, rs1s, rs2s);
1537                 }
1538 #if defined(TARGET_RISCV64)
1539                 else {
1540                     /* C.ADDW (RV64/128) */
1541                     gen_arith(ctx, OPC_RISC_ADDW, rs1s, rs1s, rs2s);
1542                 }
1543 #endif
1544                 break;
1545             case 2:
1546                 /* C.OR -> or rs1', rs1', rs2' */
1547                 gen_arith(ctx, OPC_RISC_OR, rs1s, rs1s, rs2s);
1548                 break;
1549             case 3:
1550                 /* C.AND -> and rs1', rs1', rs2' */
1551                 gen_arith(ctx, OPC_RISC_AND, rs1s, rs1s, rs2s);
1552                 break;
1553             }
1554             break;
1555         }
1556         break;
1557     case 5:
1558         /* C.J -> jal x0, offset[11:1]*/
1559         gen_jal(env, ctx, 0, GET_C_J_IMM(ctx->opcode));
1560         break;
1561     case 6:
1562         /* C.BEQZ -> beq rs1', x0, offset[8:1]*/
1563         rs1s = GET_C_RS1S(ctx->opcode);
1564         gen_branch(env, ctx, OPC_RISC_BEQ, rs1s, 0, GET_C_B_IMM(ctx->opcode));
1565         break;
1566     case 7:
1567         /* C.BNEZ -> bne rs1', x0, offset[8:1]*/
1568         rs1s = GET_C_RS1S(ctx->opcode);
1569         gen_branch(env, ctx, OPC_RISC_BNE, rs1s, 0, GET_C_B_IMM(ctx->opcode));
1570         break;
1571     }
1572 }
1573 
1574 static void decode_RV32_64C2(CPURISCVState *env, DisasContext *ctx)
1575 {
1576     uint8_t rd, rs2;
1577     uint8_t funct3 = extract32(ctx->opcode, 13, 3);
1578 
1579 
1580     rd = GET_RD(ctx->opcode);
1581 
1582     switch (funct3) {
1583     case 0: /* C.SLLI -> slli rd, rd, shamt[5:0]
1584                C.SLLI64 -> */
1585         gen_arith_imm(ctx, OPC_RISC_SLLI, rd, rd, GET_C_ZIMM(ctx->opcode));
1586         break;
1587     case 1: /* C.FLDSP(RV32/64DC) -> fld rd, offset[8:3](x2) */
1588         gen_fp_load(ctx, OPC_RISC_FLD, rd, 2, GET_C_LDSP_IMM(ctx->opcode));
1589         break;
1590     case 2: /* C.LWSP -> lw rd, offset[7:2](x2) */
1591         gen_load(ctx, OPC_RISC_LW, rd, 2, GET_C_LWSP_IMM(ctx->opcode));
1592         break;
1593     case 3:
1594 #if defined(TARGET_RISCV64)
1595         /* C.LDSP(RVC64) -> ld rd, offset[8:3](x2) */
1596         gen_load(ctx, OPC_RISC_LD, rd, 2, GET_C_LDSP_IMM(ctx->opcode));
1597 #else
1598         /* C.FLWSP(RV32FC) -> flw rd, offset[7:2](x2) */
1599         gen_fp_load(ctx, OPC_RISC_FLW, rd, 2, GET_C_LWSP_IMM(ctx->opcode));
1600 #endif
1601         break;
1602     case 4:
1603         rs2 = GET_C_RS2(ctx->opcode);
1604 
1605         if (extract32(ctx->opcode, 12, 1) == 0) {
1606             if (rs2 == 0) {
1607                 /* C.JR -> jalr x0, rs1, 0*/
1608                 gen_jalr(env, ctx, OPC_RISC_JALR, 0, rd, 0);
1609             } else {
1610                 /* C.MV -> add rd, x0, rs2 */
1611                 gen_arith(ctx, OPC_RISC_ADD, rd, 0, rs2);
1612             }
1613         } else {
1614             if (rd == 0) {
1615                 /* C.EBREAK -> ebreak*/
1616                 gen_system(env, ctx, OPC_RISC_ECALL, 0, 0, 0x1);
1617             } else {
1618                 if (rs2 == 0) {
1619                     /* C.JALR -> jalr x1, rs1, 0*/
1620                     gen_jalr(env, ctx, OPC_RISC_JALR, 1, rd, 0);
1621                 } else {
1622                     /* C.ADD -> add rd, rd, rs2 */
1623                     gen_arith(ctx, OPC_RISC_ADD, rd, rd, rs2);
1624                 }
1625             }
1626         }
1627         break;
1628     case 5:
1629         /* C.FSDSP -> fsd rs2, offset[8:3](x2)*/
1630         gen_fp_store(ctx, OPC_RISC_FSD, 2, GET_C_RS2(ctx->opcode),
1631                      GET_C_SDSP_IMM(ctx->opcode));
1632         /* C.SQSP */
1633         break;
1634     case 6: /* C.SWSP -> sw rs2, offset[7:2](x2)*/
1635         gen_store(ctx, OPC_RISC_SW, 2, GET_C_RS2(ctx->opcode),
1636                   GET_C_SWSP_IMM(ctx->opcode));
1637         break;
1638     case 7:
1639 #if defined(TARGET_RISCV64)
1640         /* C.SDSP(Rv64/128) -> sd rs2, offset[8:3](x2)*/
1641         gen_store(ctx, OPC_RISC_SD, 2, GET_C_RS2(ctx->opcode),
1642                   GET_C_SDSP_IMM(ctx->opcode));
1643 #else
1644         /* C.FSWSP(RV32) -> fsw rs2, offset[7:2](x2) */
1645         gen_fp_store(ctx, OPC_RISC_FSW, 2, GET_C_RS2(ctx->opcode),
1646                      GET_C_SWSP_IMM(ctx->opcode));
1647 #endif
1648         break;
1649     }
1650 }
1651 
1652 static void decode_RV32_64C(CPURISCVState *env, DisasContext *ctx)
1653 {
1654     uint8_t op = extract32(ctx->opcode, 0, 2);
1655 
1656     switch (op) {
1657     case 0:
1658         decode_RV32_64C0(ctx);
1659         break;
1660     case 1:
1661         decode_RV32_64C1(env, ctx);
1662         break;
1663     case 2:
1664         decode_RV32_64C2(env, ctx);
1665         break;
1666     }
1667 }
1668 
1669 static void decode_RV32_64G(CPURISCVState *env, DisasContext *ctx)
1670 {
1671     int rs1;
1672     int rs2;
1673     int rd;
1674     uint32_t op;
1675     target_long imm;
1676 
1677     /* We do not do misaligned address check here: the address should never be
1678      * misaligned at this point. Instructions that set PC must do the check,
1679      * since epc must be the address of the instruction that caused us to
1680      * perform the misaligned instruction fetch */
1681 
1682     op = MASK_OP_MAJOR(ctx->opcode);
1683     rs1 = GET_RS1(ctx->opcode);
1684     rs2 = GET_RS2(ctx->opcode);
1685     rd = GET_RD(ctx->opcode);
1686     imm = GET_IMM(ctx->opcode);
1687 
1688     switch (op) {
1689     case OPC_RISC_LUI:
1690         if (rd == 0) {
1691             break; /* NOP */
1692         }
1693         tcg_gen_movi_tl(cpu_gpr[rd], sextract64(ctx->opcode, 12, 20) << 12);
1694         break;
1695     case OPC_RISC_AUIPC:
1696         if (rd == 0) {
1697             break; /* NOP */
1698         }
1699         tcg_gen_movi_tl(cpu_gpr[rd], (sextract64(ctx->opcode, 12, 20) << 12) +
1700                ctx->base.pc_next);
1701         break;
1702     case OPC_RISC_JAL:
1703         imm = GET_JAL_IMM(ctx->opcode);
1704         gen_jal(env, ctx, rd, imm);
1705         break;
1706     case OPC_RISC_JALR:
1707         gen_jalr(env, ctx, MASK_OP_JALR(ctx->opcode), rd, rs1, imm);
1708         break;
1709     case OPC_RISC_BRANCH:
1710         gen_branch(env, ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
1711                    GET_B_IMM(ctx->opcode));
1712         break;
1713     case OPC_RISC_LOAD:
1714         gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
1715         break;
1716     case OPC_RISC_STORE:
1717         gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
1718                   GET_STORE_IMM(ctx->opcode));
1719         break;
1720     case OPC_RISC_ARITH_IMM:
1721 #if defined(TARGET_RISCV64)
1722     case OPC_RISC_ARITH_IMM_W:
1723 #endif
1724         if (rd == 0) {
1725             break; /* NOP */
1726         }
1727         gen_arith_imm(ctx, MASK_OP_ARITH_IMM(ctx->opcode), rd, rs1, imm);
1728         break;
1729     case OPC_RISC_ARITH:
1730 #if defined(TARGET_RISCV64)
1731     case OPC_RISC_ARITH_W:
1732 #endif
1733         if (rd == 0) {
1734             break; /* NOP */
1735         }
1736         gen_arith(ctx, MASK_OP_ARITH(ctx->opcode), rd, rs1, rs2);
1737         break;
1738     case OPC_RISC_FP_LOAD:
1739         gen_fp_load(ctx, MASK_OP_FP_LOAD(ctx->opcode), rd, rs1, imm);
1740         break;
1741     case OPC_RISC_FP_STORE:
1742         gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
1743                      GET_STORE_IMM(ctx->opcode));
1744         break;
1745     case OPC_RISC_ATOMIC:
1746         gen_atomic(ctx, MASK_OP_ATOMIC(ctx->opcode), rd, rs1, rs2);
1747         break;
1748     case OPC_RISC_FMADD:
1749         gen_fp_fmadd(ctx, MASK_OP_FP_FMADD(ctx->opcode), rd, rs1, rs2,
1750                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1751         break;
1752     case OPC_RISC_FMSUB:
1753         gen_fp_fmsub(ctx, MASK_OP_FP_FMSUB(ctx->opcode), rd, rs1, rs2,
1754                      GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1755         break;
1756     case OPC_RISC_FNMSUB:
1757         gen_fp_fnmsub(ctx, MASK_OP_FP_FNMSUB(ctx->opcode), rd, rs1, rs2,
1758                       GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1759         break;
1760     case OPC_RISC_FNMADD:
1761         gen_fp_fnmadd(ctx, MASK_OP_FP_FNMADD(ctx->opcode), rd, rs1, rs2,
1762                       GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
1763         break;
1764     case OPC_RISC_FP_ARITH:
1765         gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
1766                      GET_RM(ctx->opcode));
1767         break;
1768     case OPC_RISC_FENCE:
1769 #ifndef CONFIG_USER_ONLY
1770         if (ctx->opcode & 0x1000) {
1771             /* FENCE_I is a no-op in QEMU,
1772              * however we need to end the translation block */
1773             tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
1774             tcg_gen_exit_tb(NULL, 0);
1775             ctx->base.is_jmp = DISAS_NORETURN;
1776         } else {
1777             /* FENCE is a full memory barrier. */
1778             tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1779         }
1780 #endif
1781         break;
1782     case OPC_RISC_SYSTEM:
1783         gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
1784                    (ctx->opcode & 0xFFF00000) >> 20);
1785         break;
1786     default:
1787         gen_exception_illegal(ctx);
1788         break;
1789     }
1790 }
1791 
1792 static void decode_opc(CPURISCVState *env, DisasContext *ctx)
1793 {
1794     /* check for compressed insn */
1795     if (extract32(ctx->opcode, 0, 2) != 3) {
1796         if (!riscv_has_ext(env, RVC)) {
1797             gen_exception_illegal(ctx);
1798         } else {
1799             ctx->pc_succ_insn = ctx->base.pc_next + 2;
1800             decode_RV32_64C(env, ctx);
1801         }
1802     } else {
1803         ctx->pc_succ_insn = ctx->base.pc_next + 4;
1804         decode_RV32_64G(env, ctx);
1805     }
1806 }
1807 
1808 static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
1809 {
1810     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1811 
1812     ctx->pc_succ_insn = ctx->base.pc_first;
1813     ctx->flags = ctx->base.tb->flags;
1814     ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
1815     ctx->frm = -1;  /* unknown rounding mode */
1816 }
1817 
1818 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
1819 {
1820 }
1821 
1822 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1823 {
1824     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1825 
1826     tcg_gen_insn_start(ctx->base.pc_next);
1827 }
1828 
1829 static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
1830                                       const CPUBreakpoint *bp)
1831 {
1832     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1833 
1834     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
1835     ctx->base.is_jmp = DISAS_NORETURN;
1836     gen_exception_debug();
1837     /* The address covered by the breakpoint must be included in
1838        [tb->pc, tb->pc + tb->size) in order to for it to be
1839        properly cleared -- thus we increment the PC here so that
1840        the logic setting tb->size below does the right thing.  */
1841     ctx->base.pc_next += 4;
1842     return true;
1843 }
1844 
1845 
1846 static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1847 {
1848     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1849     CPURISCVState *env = cpu->env_ptr;
1850 
1851     ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
1852     decode_opc(env, ctx);
1853     ctx->base.pc_next = ctx->pc_succ_insn;
1854 
1855     if (ctx->base.is_jmp == DISAS_NEXT) {
1856         target_ulong page_start;
1857 
1858         page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
1859         if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
1860             ctx->base.is_jmp = DISAS_TOO_MANY;
1861         }
1862     }
1863 }
1864 
1865 static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1866 {
1867     DisasContext *ctx = container_of(dcbase, DisasContext, base);
1868 
1869     switch (ctx->base.is_jmp) {
1870     case DISAS_TOO_MANY:
1871         gen_goto_tb(ctx, 0, ctx->base.pc_next);
1872         break;
1873     case DISAS_NORETURN:
1874         break;
1875     default:
1876         g_assert_not_reached();
1877     }
1878 }
1879 
1880 static void riscv_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
1881 {
1882     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
1883     log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
1884 }
1885 
1886 static const TranslatorOps riscv_tr_ops = {
1887     .init_disas_context = riscv_tr_init_disas_context,
1888     .tb_start           = riscv_tr_tb_start,
1889     .insn_start         = riscv_tr_insn_start,
1890     .breakpoint_check   = riscv_tr_breakpoint_check,
1891     .translate_insn     = riscv_tr_translate_insn,
1892     .tb_stop            = riscv_tr_tb_stop,
1893     .disas_log          = riscv_tr_disas_log,
1894 };
1895 
1896 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
1897 {
1898     DisasContext ctx;
1899 
1900     translator_loop(&riscv_tr_ops, &ctx.base, cs, tb);
1901 }
1902 
1903 void riscv_translate_init(void)
1904 {
1905     int i;
1906 
1907     /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
1908     /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
1909     /* registers, unless you specifically block reads/writes to reg 0 */
1910     cpu_gpr[0] = NULL;
1911 
1912     for (i = 1; i < 32; i++) {
1913         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
1914             offsetof(CPURISCVState, gpr[i]), riscv_int_regnames[i]);
1915     }
1916 
1917     for (i = 0; i < 32; i++) {
1918         cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
1919             offsetof(CPURISCVState, fpr[i]), riscv_fpr_regnames[i]);
1920     }
1921 
1922     cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, pc), "pc");
1923     load_res = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_res),
1924                              "load_res");
1925     load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
1926                              "load_val");
1927 }
1928