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