master
c 1,505 lines 42.9 KB
Raw
1 /*
2 * RISC-V emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "qemu/osdep.h"
20 #include "qemu/log.h"
21 #include "cpu.h"
22 #include "tcg/tcg-op.h"
23 #include "exec/helper-proto.h"
24 #include "exec/helper-gen.h"
25 #include "exec/target_page.h"
26 #include "exec/translator.h"
27 #include "accel/tcg/cpu-ldst.h"
28 #include "exec/translation-block.h"
29 #include "exec/log.h"
30 #include "semihosting/semihost.h"
31
32 #include "internals.h"
33
34 #define HELPER_H "helper.h"
35 #include "exec/helper-info.c.inc"
36 #undef HELPER_H
37
38 #include "tcg/tcg-cpu.h"
39
40 /* global register indices */
41 static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc;
42 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
43 static TCGv_i32 cpu_vl, cpu_vstart;
44 static TCGv load_res;
45 static TCGv load_val;
46
47 /*
48 * If an operation is being performed on less than TARGET_LONG_BITS,
49 * it may require the inputs to be sign- or zero-extended; which will
50 * depend on the exact operation being performed.
51 */
52 typedef enum {
53 EXT_NONE,
54 EXT_SIGN,
55 EXT_ZERO,
56 } DisasExtend;
57
58 typedef struct DisasContext {
59 DisasContextBase base;
60 target_ulong cur_insn_len;
61 target_ulong pc_save;
62 uint32_t priv_ver;
63 RISCVMXL misa_mxl_max;
64 RISCVMXL xl;
65 RISCVMXL address_xl;
66 uint32_t misa_ext;
67 uint32_t opcode;
68 RISCVExtStatus mstatus_fs;
69 RISCVExtStatus mstatus_vs;
70 uint32_t mem_idx;
71 privilege_mode_t priv;
72 /*
73 * Remember the rounding mode encoded in the previous fp instruction,
74 * which we have already installed into env->fp_status. Or -1 for
75 * no previous fp instruction. Note that we exit the TB when writing
76 * to any system register, which includes CSR_FRM, so we do not have
77 * to reset this known value.
78 */
79 int frm;
80 RISCVMXL ol;
81 bool virt_inst_excp;
82 bool virt_enabled;
83 const RISCVCPUConfig *cfg_ptr;
84 /* vector extension */
85 bool vill;
86 /*
87 * Encode LMUL to lmul as follows:
88 * LMUL vlmul lmul
89 * 1 000 0
90 * 2 001 1
91 * 4 010 2
92 * 8 011 3
93 * - 100 -
94 * 1/8 101 -3
95 * 1/4 110 -2
96 * 1/2 111 -1
97 */
98 int8_t lmul;
99 uint8_t sew;
100 uint8_t vta;
101 uint8_t vma;
102 bool cfg_vta_all_1s;
103 bool vstart_eq_zero;
104 bool vl_eq_vlmax;
105 bool altfmt;
106 CPUState *cs;
107 TCGv zero;
108 /* actual address width */
109 uint8_t addr_xl;
110 bool addr_signed;
111 /* Ztso */
112 bool ztso;
113 /* Use icount trigger for native debug */
114 bool itrigger;
115 /* FRM is known to contain a valid value. */
116 bool frm_valid;
117 bool insn_start_updated;
118 const GPtrArray *decoders;
119 /* zicfilp extension. fcfi_enabled, lp expected or not */
120 bool fcfi_enabled;
121 bool fcfi_lp_expected;
122 /* zicfiss extension, if shadow stack was enabled during TB gen */
123 bool bcfi_enabled;
124 /* Data endianness from MSTATUS UBE/SBE/MBE */
125 MemOp mo_endianness;
126 } DisasContext;
127
128 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
129 {
130 return ctx->misa_ext & ext;
131 }
132
133 #ifdef TARGET_RISCV32
134 #define get_xl(ctx) MXL_RV32
135 #elif defined(CONFIG_USER_ONLY)
136 #define get_xl(ctx) MXL_RV64
137 #else
138 #define get_xl(ctx) ((ctx)->xl)
139 #endif
140
141 #ifdef TARGET_RISCV32
142 #define get_address_xl(ctx) MXL_RV32
143 #elif defined(CONFIG_USER_ONLY)
144 #define get_address_xl(ctx) MXL_RV64
145 #else
146 #define get_address_xl(ctx) ((ctx)->address_xl)
147 #endif
148
149 #define mxl_memop(ctx) ((get_xl(ctx) + 1) | (ctx)->mo_endianness)
150
151 /* The word size for this machine mode. */
152 static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
153 {
154 return 16 << get_xl(ctx);
155 }
156
157 /* The operation length, as opposed to the xlen. */
158 #ifdef TARGET_RISCV32
159 #define get_ol(ctx) MXL_RV32
160 #else
161 #define get_ol(ctx) ((ctx)->ol)
162 #endif
163
164 static inline int get_olen(DisasContext *ctx)
165 {
166 return 16 << get_ol(ctx);
167 }
168
169 /* The maximum register length */
170 #ifdef TARGET_RISCV32
171 #define get_xl_max(ctx) MXL_RV32
172 #else
173 #define get_xl_max(ctx) ((ctx)->misa_mxl_max)
174 #endif
175
176 /*
177 * RISC-V requires NaN-boxing of narrower width floating point values.
178 * This applies when a 32-bit value is assigned to a 64-bit FP register.
179 * For consistency and simplicity, we nanbox results even when the RVD
180 * extension is not present.
181 */
182 static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
183 {
184 tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32));
185 }
186
187 static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in)
188 {
189 tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(16, 48));
190 }
191
192 /*
193 * A narrow n-bit operation, where n < FLEN, checks that input operands
194 * are correctly Nan-boxed, i.e., all upper FLEN - n bits are 1.
195 * If so, the least-significant bits of the input are used, otherwise the
196 * input value is treated as an n-bit canonical NaN (v2.2 section 9.2).
197 *
198 * Here, the result is always nan-boxed, even the canonical nan.
199 */
200 static void gen_check_nanbox_h(TCGv_i64 out, TCGv_i64 in)
201 {
202 TCGv_i64 t_max = tcg_constant_i64(0xffffffffffff0000ull);
203 TCGv_i64 t_nan = tcg_constant_i64(0xffffffffffff7e00ull);
204
205 tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
206 }
207
208 static void gen_check_nanbox_h_bf16(TCGv_i64 out, TCGv_i64 in)
209 {
210 TCGv_i64 t_max = tcg_constant_i64(0xffffffffffff0000ull);
211 TCGv_i64 t_nan = tcg_constant_i64(0xffffffffffff7fc0ull);
212
213 tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
214 }
215
216 static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
217 {
218 TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
219 TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
220
221 tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
222 }
223
224 static void decode_save_opc(DisasContext *ctx, uint64_t excp_uw2)
225 {
226 assert(!ctx->insn_start_updated);
227 ctx->insn_start_updated = true;
228 tcg_set_insn_start_param(ctx->base.insn_start, 1, ctx->opcode);
229 tcg_set_insn_start_param(ctx->base.insn_start, 2, excp_uw2);
230 }
231
232 static void gen_pc_plus_diff(TCGv target, DisasContext *ctx,
233 target_long diff)
234 {
235 target_ulong dest = ctx->base.pc_next + diff;
236
237 assert(ctx->pc_save != -1);
238 if (tb_cflags(ctx->base.tb) & CF_PCREL) {
239 tcg_gen_addi_tl(target, cpu_pc, dest - ctx->pc_save);
240 if (get_xl(ctx) == MXL_RV32) {
241 tcg_gen_ext32s_tl(target, target);
242 }
243 } else {
244 if (get_xl(ctx) == MXL_RV32) {
245 dest = (int32_t)dest;
246 }
247 tcg_gen_movi_tl(target, dest);
248 }
249 }
250
251 static void gen_update_pc(DisasContext *ctx, target_long diff)
252 {
253 gen_pc_plus_diff(cpu_pc, ctx, diff);
254 ctx->pc_save = ctx->base.pc_next + diff;
255 }
256
257 static void generate_exception(DisasContext *ctx, RISCVException excp)
258 {
259 gen_update_pc(ctx, 0);
260 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
261 ctx->base.is_jmp = DISAS_NORETURN;
262 }
263
264 static void gen_exception_illegal(DisasContext *ctx)
265 {
266 tcg_gen_st_i64(tcg_constant_i64(ctx->opcode), tcg_env,
267 offsetof(CPURISCVState, bins));
268 if (ctx->virt_inst_excp) {
269 generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
270 } else {
271 generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
272 }
273 }
274
275 static void gen_exception_inst_addr_mis(DisasContext *ctx, TCGv target)
276 {
277 TCGv_i64 ext = tcg_temp_new_i64();
278 tcg_gen_extu_tl_i64(ext, target);
279 tcg_gen_st_i64(ext, tcg_env, offsetof(CPURISCVState, badaddr));
280 generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
281 }
282
283 static void lookup_and_goto_ptr(DisasContext *ctx)
284 {
285 #ifndef CONFIG_USER_ONLY
286 if (ctx->itrigger) {
287 gen_helper_itrigger_match(tcg_env);
288 }
289 #endif
290 tcg_gen_lookup_and_goto_ptr();
291 }
292
293 static void exit_tb(DisasContext *ctx)
294 {
295 #ifndef CONFIG_USER_ONLY
296 if (ctx->itrigger) {
297 gen_helper_itrigger_match(tcg_env);
298 }
299 #endif
300 tcg_gen_exit_tb(NULL, 0);
301 }
302
303 static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_idx,
304 target_long diff)
305 {
306 target_ulong dest = ctx->base.pc_next + diff;
307
308 /*
309 * Under itrigger, instruction executes one by one like singlestep,
310 * direct block chain benefits will be small.
311 */
312 if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
313 /*
314 * For pcrel, the pc must always be up-to-date on entry to
315 * the linked TB, so that it can use simple additions for all
316 * further adjustments. For !pcrel, the linked TB is compiled
317 * to know its full virtual address, so we can delay the
318 * update to pc to the unlinked path. A long chain of links
319 * can thus avoid many updates to the PC.
320 */
321 if (tb_cflags(ctx->base.tb) & CF_PCREL) {
322 gen_update_pc(ctx, diff);
323 tcg_gen_goto_tb(tb_slot_idx);
324 } else {
325 tcg_gen_goto_tb(tb_slot_idx);
326 gen_update_pc(ctx, diff);
327 }
328 tcg_gen_exit_tb(ctx->base.tb, tb_slot_idx);
329 } else {
330 gen_update_pc(ctx, diff);
331 lookup_and_goto_ptr(ctx);
332 }
333 }
334
335 /*
336 * Wrappers for getting reg values.
337 *
338 * The $zero register does not have cpu_gpr[0] allocated -- we supply the
339 * constant zero as a source, and an uninitialized sink as destination.
340 *
341 * Further, we may provide an extension for word operations.
342 */
343 static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
344 {
345 TCGv t;
346
347 if (reg_num == 0) {
348 return ctx->zero;
349 }
350
351 switch (get_ol(ctx)) {
352 case MXL_RV32:
353 switch (ext) {
354 case EXT_NONE:
355 break;
356 case EXT_SIGN:
357 t = tcg_temp_new();
358 tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
359 return t;
360 case EXT_ZERO:
361 t = tcg_temp_new();
362 tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
363 return t;
364 default:
365 g_assert_not_reached();
366 }
367 break;
368 case MXL_RV64:
369 case MXL_RV128:
370 break;
371 default:
372 g_assert_not_reached();
373 }
374 return cpu_gpr[reg_num];
375 }
376
377 static TCGv get_gprh(DisasContext *ctx, int reg_num)
378 {
379 assert(get_xl(ctx) == MXL_RV128);
380 if (reg_num == 0) {
381 return ctx->zero;
382 }
383 return cpu_gprh[reg_num];
384 }
385
386 static TCGv dest_gpr(DisasContext *ctx, int reg_num)
387 {
388 if (reg_num == 0 || get_olen(ctx) < TARGET_LONG_BITS) {
389 return tcg_temp_new();
390 }
391 return cpu_gpr[reg_num];
392 }
393
394 static TCGv dest_gprh(DisasContext *ctx, int reg_num)
395 {
396 if (reg_num == 0) {
397 return tcg_temp_new();
398 }
399 return cpu_gprh[reg_num];
400 }
401
402 static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
403 {
404 if (reg_num != 0) {
405 switch (get_ol(ctx)) {
406 case MXL_RV32:
407 tcg_gen_ext32s_tl(cpu_gpr[reg_num], t);
408 break;
409 case MXL_RV64:
410 case MXL_RV128:
411 tcg_gen_mov_tl(cpu_gpr[reg_num], t);
412 break;
413 default:
414 g_assert_not_reached();
415 }
416
417 if (get_xl_max(ctx) == MXL_RV128) {
418 tcg_gen_sari_tl(cpu_gprh[reg_num], cpu_gpr[reg_num], 63);
419 }
420 }
421 }
422
423 static void gen_set_gpri(DisasContext *ctx, int reg_num, target_long imm)
424 {
425 if (reg_num != 0) {
426 switch (get_ol(ctx)) {
427 case MXL_RV32:
428 tcg_gen_movi_tl(cpu_gpr[reg_num], (int32_t)imm);
429 break;
430 case MXL_RV64:
431 case MXL_RV128:
432 tcg_gen_movi_tl(cpu_gpr[reg_num], imm);
433 break;
434 default:
435 g_assert_not_reached();
436 }
437
438 if (get_xl_max(ctx) == MXL_RV128) {
439 tcg_gen_movi_tl(cpu_gprh[reg_num], -(imm < 0));
440 }
441 }
442 }
443
444 static void gen_set_gpr128(DisasContext *ctx, int reg_num, TCGv rl, TCGv rh)
445 {
446 assert(get_ol(ctx) == MXL_RV128);
447 if (reg_num != 0) {
448 tcg_gen_mov_tl(cpu_gpr[reg_num], rl);
449 tcg_gen_mov_tl(cpu_gprh[reg_num], rh);
450 }
451 }
452
453 static TCGv_i64 get_fpr_hs(DisasContext *ctx, int reg_num)
454 {
455 if (!ctx->cfg_ptr->ext_zfinx) {
456 return cpu_fpr[reg_num];
457 }
458
459 if (reg_num == 0) {
460 return tcg_constant_i64(0);
461 }
462 switch (get_xl(ctx)) {
463 case MXL_RV32:
464 #ifdef TARGET_RISCV32
465 {
466 TCGv_i64 t = tcg_temp_new_i64();
467 tcg_gen_ext_i32_i64(t, cpu_gpr[reg_num]);
468 return t;
469 }
470 #else
471 /* fall through */
472 case MXL_RV64:
473 return cpu_gpr[reg_num];
474 #endif
475 default:
476 g_assert_not_reached();
477 }
478 }
479
480 static TCGv_i64 get_fpr_d(DisasContext *ctx, int reg_num)
481 {
482 if (!ctx->cfg_ptr->ext_zfinx) {
483 return cpu_fpr[reg_num];
484 }
485
486 if (reg_num == 0) {
487 return tcg_constant_i64(0);
488 }
489 switch (get_xl(ctx)) {
490 case MXL_RV32:
491 {
492 TCGv_i64 t = tcg_temp_new_i64();
493 tcg_gen_concat_tl_i64(t, cpu_gpr[reg_num], cpu_gpr[reg_num + 1]);
494 return t;
495 }
496 #ifdef TARGET_RISCV64
497 case MXL_RV64:
498 return cpu_gpr[reg_num];
499 #endif
500 default:
501 g_assert_not_reached();
502 }
503 }
504
505 static TCGv_i64 dest_fpr(DisasContext *ctx, int reg_num)
506 {
507 if (!ctx->cfg_ptr->ext_zfinx) {
508 return cpu_fpr[reg_num];
509 }
510
511 if (reg_num == 0) {
512 return tcg_temp_new_i64();
513 }
514
515 switch (get_xl(ctx)) {
516 case MXL_RV32:
517 return tcg_temp_new_i64();
518 #ifdef TARGET_RISCV64
519 case MXL_RV64:
520 return cpu_gpr[reg_num];
521 #endif
522 default:
523 g_assert_not_reached();
524 }
525 }
526
527 /* assume it is nanboxing (for normal) or sign-extended (for zfinx) */
528 static void gen_set_fpr_hs(DisasContext *ctx, int reg_num, TCGv_i64 t)
529 {
530 if (!ctx->cfg_ptr->ext_zfinx) {
531 tcg_gen_mov_i64(cpu_fpr[reg_num], t);
532 return;
533 }
534 if (reg_num != 0) {
535 switch (get_xl(ctx)) {
536 case MXL_RV32:
537 #ifdef TARGET_RISCV32
538 tcg_gen_extrl_i64_i32(cpu_gpr[reg_num], t);
539 break;
540 #else
541 /* fall through */
542 case MXL_RV64:
543 tcg_gen_mov_i64(cpu_gpr[reg_num], t);
544 break;
545 #endif
546 default:
547 g_assert_not_reached();
548 }
549 }
550 }
551
552 static void gen_set_fpr_d(DisasContext *ctx, int reg_num, TCGv_i64 t)
553 {
554 if (!ctx->cfg_ptr->ext_zfinx) {
555 tcg_gen_mov_i64(cpu_fpr[reg_num], t);
556 return;
557 }
558
559 if (reg_num != 0) {
560 switch (get_xl(ctx)) {
561 case MXL_RV32:
562 #ifdef TARGET_RISCV32
563 tcg_gen_extr_i64_i32(cpu_gpr[reg_num], cpu_gpr[reg_num + 1], t);
564 break;
565 #else
566 tcg_gen_ext32s_i64(cpu_gpr[reg_num], t);
567 tcg_gen_sari_i64(cpu_gpr[reg_num + 1], t, 32);
568 break;
569 case MXL_RV64:
570 tcg_gen_mov_i64(cpu_gpr[reg_num], t);
571 break;
572 #endif
573 default:
574 g_assert_not_reached();
575 }
576 }
577 }
578
579 #ifndef CONFIG_USER_ONLY
580 /*
581 * Direct calls
582 * - jal x1;
583 * - jal x5;
584 * - c.jal.
585 * - cm.jalt.
586 *
587 * Direct jumps
588 * - jal x0;
589 * - c.j;
590 * - cm.jt.
591 *
592 * Other direct jumps
593 * - jal rd where rd != x1 and rd != x5 and rd != x0;
594 */
595 static void gen_ctr_jal(DisasContext *ctx, int rd, target_ulong imm)
596 {
597 TCGv dest = tcg_temp_new();
598 TCGv src = tcg_temp_new();
599 TCGv type;
600
601 /*
602 * If rd is x1 or x5 link registers, treat this as direct call otherwise
603 * its a direct jump.
604 */
605 if (rd == 1 || rd == 5) {
606 type = tcg_constant_tl(CTRDATA_TYPE_DIRECT_CALL);
607 } else if (rd == 0) {
608 type = tcg_constant_tl(CTRDATA_TYPE_DIRECT_JUMP);
609 } else {
610 type = tcg_constant_tl(CTRDATA_TYPE_OTHER_DIRECT_JUMP);
611 }
612
613 gen_pc_plus_diff(dest, ctx, imm);
614 gen_pc_plus_diff(src, ctx, 0);
615 gen_helper_ctr_add_entry(tcg_env, src, dest, type);
616 }
617 #endif
618
619 static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
620 {
621 TCGv succ_pc = dest_gpr(ctx, rd);
622
623 /* check misaligned: */
624 if (!riscv_cpu_allow_16bit_insn(ctx->cfg_ptr,
625 ctx->priv_ver,
626 ctx->misa_ext)) {
627 if ((imm & 0x3) != 0) {
628 TCGv target_pc = tcg_temp_new();
629 gen_pc_plus_diff(target_pc, ctx, imm);
630 gen_exception_inst_addr_mis(ctx, target_pc);
631 return;
632 }
633 }
634
635 #ifndef CONFIG_USER_ONLY
636 if (ctx->cfg_ptr->ext_smctr || ctx->cfg_ptr->ext_ssctr) {
637 gen_ctr_jal(ctx, rd, imm);
638 }
639 #endif
640
641 gen_pc_plus_diff(succ_pc, ctx, ctx->cur_insn_len);
642 gen_set_gpr(ctx, rd, succ_pc);
643
644 gen_goto_tb(ctx, 0, imm); /* must use this for safety */
645 ctx->base.is_jmp = DISAS_NORETURN;
646 }
647
648 /* Compute a canonical address from a register plus offset. */
649 static TCGv get_address(DisasContext *ctx, int rs1, int imm)
650 {
651 TCGv addr = tcg_temp_new();
652 TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
653
654 tcg_gen_addi_tl(addr, src1, imm);
655 if (ctx->addr_signed) {
656 tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_xl);
657 } else {
658 tcg_gen_extract_tl(addr, addr, 0, ctx->addr_xl);
659 }
660
661 return addr;
662 }
663
664 /* Compute a canonical address from a register plus reg offset. */
665 static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
666 {
667 TCGv addr = tcg_temp_new();
668 TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
669
670 tcg_gen_add_tl(addr, src1, offs);
671 if (ctx->addr_signed) {
672 tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_xl);
673 } else {
674 tcg_gen_extract_tl(addr, addr, 0, ctx->addr_xl);
675 }
676
677 return addr;
678 }
679
680 #ifndef CONFIG_USER_ONLY
681 /*
682 * We will have already diagnosed disabled state,
683 * and need to turn initial/clean into dirty.
684 */
685 static void mark_fs_dirty(DisasContext *ctx)
686 {
687 TCGv tmp;
688
689 if (!has_ext(ctx, RVF)) {
690 return;
691 }
692
693 if (ctx->mstatus_fs != EXT_STATUS_DIRTY) {
694 /* Remember the state change for the rest of the TB. */
695 ctx->mstatus_fs = EXT_STATUS_DIRTY;
696
697 tmp = tcg_temp_new();
698 tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
699 tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
700 tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
701
702 if (ctx->virt_enabled) {
703 tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
704 tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
705 tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
706 }
707 }
708 }
709 #else
710 static inline void mark_fs_dirty(DisasContext *ctx) { }
711 #endif
712
713 #ifndef CONFIG_USER_ONLY
714 /*
715 * We will have already diagnosed disabled state,
716 * and need to turn initial/clean into dirty.
717 */
718 static void mark_vs_dirty(DisasContext *ctx)
719 {
720 TCGv tmp;
721
722 if (ctx->mstatus_vs != EXT_STATUS_DIRTY) {
723 /* Remember the state change for the rest of the TB. */
724 ctx->mstatus_vs = EXT_STATUS_DIRTY;
725
726 tmp = tcg_temp_new();
727 tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
728 tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
729 tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus));
730
731 if (ctx->virt_enabled) {
732 tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
733 tcg_gen_ori_tl(tmp, tmp, MSTATUS_VS);
734 tcg_gen_st_tl(tmp, tcg_env, offsetof(CPURISCVState, mstatus_hs));
735 }
736 }
737 }
738 #else
739 static inline void mark_vs_dirty(DisasContext *ctx) { }
740 #endif
741
742 static void finalize_rvv_inst(DisasContext *ctx)
743 {
744 mark_vs_dirty(ctx);
745 ctx->vstart_eq_zero = true;
746 }
747
748 static void gen_set_rm(DisasContext *ctx, uint8_t rm)
749 {
750 if (ctx->frm == rm) {
751 return;
752 }
753 ctx->frm = rm;
754
755 if (rm == RISCV_FRM_DYN) {
756 /* The helper will return only if frm valid. */
757 ctx->frm_valid = true;
758 }
759
760 /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
761 decode_save_opc(ctx, 0);
762 gen_helper_set_rounding_mode(tcg_env, tcg_constant_i32(rm));
763 }
764
765 static void gen_set_rm_chkfrm(DisasContext *ctx, uint8_t rm)
766 {
767 if (ctx->frm == rm && ctx->frm_valid) {
768 return;
769 }
770 ctx->frm = rm;
771 ctx->frm_valid = true;
772
773 /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
774 decode_save_opc(ctx, 0);
775 gen_helper_set_rounding_mode_chkfrm(tcg_env, tcg_constant_i32(rm));
776 }
777
778 static int ex_plus_1(DisasContext *ctx, int nf)
779 {
780 return nf + 1;
781 }
782
783 #define EX_SH(amount) \
784 static int ex_shift_##amount(DisasContext *ctx, int imm) \
785 { \
786 return imm << amount; \
787 }
788 EX_SH(1)
789 EX_SH(2)
790 EX_SH(3)
791 EX_SH(4)
792 EX_SH(12)
793
794 #define REQUIRE_EXT(ctx, ext) do { \
795 if (!has_ext(ctx, ext)) { \
796 return false; \
797 } \
798 } while (0)
799
800 #define REQUIRE_32BIT(ctx) do { \
801 if (get_xl(ctx) != MXL_RV32) { \
802 return false; \
803 } \
804 } while (0)
805
806 #define REQUIRE_64BIT(ctx) do { \
807 if (get_xl(ctx) != MXL_RV64) { \
808 return false; \
809 } \
810 } while (0)
811
812 #define REQUIRE_128BIT(ctx) do { \
813 if (get_xl(ctx) != MXL_RV128) { \
814 return false; \
815 } \
816 } while (0)
817
818 #define REQUIRE_64_OR_128BIT(ctx) do { \
819 if (get_xl(ctx) == MXL_RV32) { \
820 return false; \
821 } \
822 } while (0)
823
824 #define REQUIRE_EITHER_EXT(ctx, A, B) do { \
825 if (!ctx->cfg_ptr->ext_##A && \
826 !ctx->cfg_ptr->ext_##B) { \
827 return false; \
828 } \
829 } while (0)
830
831 static int ex_rvc_register(DisasContext *ctx, int reg)
832 {
833 return 8 + reg;
834 }
835
836 static int ex_sreg_register(DisasContext *ctx, int reg)
837 {
838 return reg < 2 ? reg + 8 : reg + 16;
839 }
840
841 static int ex_rvc_shiftli(DisasContext *ctx, int imm)
842 {
843 /* For RV128 a shamt of 0 means a shift by 64. */
844 if (get_ol(ctx) == MXL_RV128) {
845 imm = imm ? imm : 64;
846 }
847 return imm;
848 }
849
850 static int ex_rvc_shiftri(DisasContext *ctx, int imm)
851 {
852 /*
853 * For RV128 a shamt of 0 means a shift by 64, furthermore, for right
854 * shifts, the shamt is sign-extended.
855 */
856 if (get_ol(ctx) == MXL_RV128) {
857 imm = imm | (imm & 32) << 1;
858 imm = imm ? imm : 64;
859 }
860 return imm;
861 }
862
863 /* Include the auto-generated decoder for 32 bit insn */
864 #include "decode-insn32.c.inc"
865
866 static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
867 void (*func)(TCGv, TCGv, target_long))
868 {
869 TCGv dest = dest_gpr(ctx, a->rd);
870 TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
871
872 func(dest, src1, a->imm);
873
874 if (get_xl(ctx) == MXL_RV128) {
875 TCGv src1h = get_gprh(ctx, a->rs1);
876 TCGv desth = dest_gprh(ctx, a->rd);
877
878 func(desth, src1h, -(a->imm < 0));
879 gen_set_gpr128(ctx, a->rd, dest, desth);
880 } else {
881 gen_set_gpr(ctx, a->rd, dest);
882 }
883
884 return true;
885 }
886
887 static bool gen_logic(DisasContext *ctx, arg_r *a,
888 void (*func)(TCGv, TCGv, TCGv))
889 {
890 TCGv dest = dest_gpr(ctx, a->rd);
891 TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
892 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
893
894 func(dest, src1, src2);
895
896 if (get_xl(ctx) == MXL_RV128) {
897 TCGv src1h = get_gprh(ctx, a->rs1);
898 TCGv src2h = get_gprh(ctx, a->rs2);
899 TCGv desth = dest_gprh(ctx, a->rd);
900
901 func(desth, src1h, src2h);
902 gen_set_gpr128(ctx, a->rd, dest, desth);
903 } else {
904 gen_set_gpr(ctx, a->rd, dest);
905 }
906
907 return true;
908 }
909
910 static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a, DisasExtend ext,
911 void (*func)(TCGv, TCGv, target_long),
912 void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long))
913 {
914 TCGv dest = dest_gpr(ctx, a->rd);
915 TCGv src1 = get_gpr(ctx, a->rs1, ext);
916
917 if (get_ol(ctx) < MXL_RV128) {
918 func(dest, src1, a->imm);
919 gen_set_gpr(ctx, a->rd, dest);
920 } else {
921 if (f128 == NULL) {
922 return false;
923 }
924
925 TCGv src1h = get_gprh(ctx, a->rs1);
926 TCGv desth = dest_gprh(ctx, a->rd);
927
928 f128(dest, desth, src1, src1h, a->imm);
929 gen_set_gpr128(ctx, a->rd, dest, desth);
930 }
931 return true;
932 }
933
934 static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, DisasExtend ext,
935 void (*func)(TCGv, TCGv, TCGv),
936 void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
937 {
938 TCGv dest = dest_gpr(ctx, a->rd);
939 TCGv src1 = get_gpr(ctx, a->rs1, ext);
940 TCGv src2 = tcg_constant_tl(a->imm);
941
942 if (get_ol(ctx) < MXL_RV128) {
943 func(dest, src1, src2);
944 gen_set_gpr(ctx, a->rd, dest);
945 } else {
946 if (f128 == NULL) {
947 return false;
948 }
949
950 TCGv src1h = get_gprh(ctx, a->rs1);
951 TCGv src2h = tcg_constant_tl(-(a->imm < 0));
952 TCGv desth = dest_gprh(ctx, a->rd);
953
954 f128(dest, desth, src1, src1h, src2, src2h);
955 gen_set_gpr128(ctx, a->rd, dest, desth);
956 }
957 return true;
958 }
959
960 static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
961 void (*func)(TCGv, TCGv, TCGv),
962 void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
963 {
964 TCGv dest = dest_gpr(ctx, a->rd);
965 TCGv src1 = get_gpr(ctx, a->rs1, ext);
966 TCGv src2 = get_gpr(ctx, a->rs2, ext);
967
968 if (get_ol(ctx) < MXL_RV128) {
969 func(dest, src1, src2);
970 gen_set_gpr(ctx, a->rd, dest);
971 } else {
972 if (f128 == NULL) {
973 return false;
974 }
975
976 TCGv src1h = get_gprh(ctx, a->rs1);
977 TCGv src2h = get_gprh(ctx, a->rs2);
978 TCGv desth = dest_gprh(ctx, a->rd);
979
980 f128(dest, desth, src1, src1h, src2, src2h);
981 gen_set_gpr128(ctx, a->rd, dest, desth);
982 }
983 return true;
984 }
985
986 static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
987 void (*f_tl)(TCGv, TCGv, TCGv),
988 void (*f_32)(TCGv, TCGv, TCGv),
989 void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv, TCGv))
990 {
991 int olen = get_olen(ctx);
992
993 if (olen != TARGET_LONG_BITS) {
994 if (olen == 32) {
995 f_tl = f_32;
996 } else if (olen != 128) {
997 g_assert_not_reached();
998 }
999 }
1000 return gen_arith(ctx, a, ext, f_tl, f_128);
1001 }
1002
1003 static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
1004 void (*func)(TCGv, TCGv, target_long),
1005 void (*f128)(TCGv, TCGv, TCGv, TCGv, target_long))
1006 {
1007 TCGv dest, src1;
1008 int max_len = get_olen(ctx);
1009
1010 if (a->shamt >= max_len) {
1011 return false;
1012 }
1013
1014 dest = dest_gpr(ctx, a->rd);
1015 src1 = get_gpr(ctx, a->rs1, ext);
1016
1017 if (max_len < 128) {
1018 func(dest, src1, a->shamt);
1019 gen_set_gpr(ctx, a->rd, dest);
1020 } else {
1021 TCGv src1h = get_gprh(ctx, a->rs1);
1022 TCGv desth = dest_gprh(ctx, a->rd);
1023
1024 if (f128 == NULL) {
1025 return false;
1026 }
1027 f128(dest, desth, src1, src1h, a->shamt);
1028 gen_set_gpr128(ctx, a->rd, dest, desth);
1029 }
1030 return true;
1031 }
1032
1033 static bool gen_shift_imm_fn_per_ol(DisasContext *ctx, arg_shift *a,
1034 DisasExtend ext,
1035 void (*f_tl)(TCGv, TCGv, target_long),
1036 void (*f_32)(TCGv, TCGv, target_long),
1037 void (*f_128)(TCGv, TCGv, TCGv, TCGv,
1038 target_long))
1039 {
1040 int olen = get_olen(ctx);
1041 if (olen != TARGET_LONG_BITS) {
1042 if (olen == 32) {
1043 f_tl = f_32;
1044 } else if (olen != 128) {
1045 g_assert_not_reached();
1046 }
1047 }
1048 return gen_shift_imm_fn(ctx, a, ext, f_tl, f_128);
1049 }
1050
1051 static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
1052 void (*func)(TCGv, TCGv, TCGv))
1053 {
1054 TCGv dest, src1, src2;
1055 int max_len = get_olen(ctx);
1056
1057 if (a->shamt >= max_len) {
1058 return false;
1059 }
1060
1061 dest = dest_gpr(ctx, a->rd);
1062 src1 = get_gpr(ctx, a->rs1, ext);
1063 src2 = tcg_constant_tl(a->shamt);
1064
1065 func(dest, src1, src2);
1066
1067 gen_set_gpr(ctx, a->rd, dest);
1068 return true;
1069 }
1070
1071 static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
1072 void (*func)(TCGv, TCGv, TCGv),
1073 void (*f128)(TCGv, TCGv, TCGv, TCGv, TCGv))
1074 {
1075 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
1076 TCGv ext2 = tcg_temp_new();
1077 int max_len = get_olen(ctx);
1078
1079 tcg_gen_andi_tl(ext2, src2, max_len - 1);
1080
1081 TCGv dest = dest_gpr(ctx, a->rd);
1082 TCGv src1 = get_gpr(ctx, a->rs1, ext);
1083
1084 if (max_len < 128) {
1085 func(dest, src1, ext2);
1086 gen_set_gpr(ctx, a->rd, dest);
1087 } else {
1088 TCGv src1h = get_gprh(ctx, a->rs1);
1089 TCGv desth = dest_gprh(ctx, a->rd);
1090
1091 if (f128 == NULL) {
1092 return false;
1093 }
1094 f128(dest, desth, src1, src1h, ext2);
1095 gen_set_gpr128(ctx, a->rd, dest, desth);
1096 }
1097 return true;
1098 }
1099
1100 static bool gen_shift_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
1101 void (*f_tl)(TCGv, TCGv, TCGv),
1102 void (*f_32)(TCGv, TCGv, TCGv),
1103 void (*f_128)(TCGv, TCGv, TCGv, TCGv, TCGv))
1104 {
1105 int olen = get_olen(ctx);
1106 if (olen != TARGET_LONG_BITS) {
1107 if (olen == 32) {
1108 f_tl = f_32;
1109 } else if (olen != 128) {
1110 g_assert_not_reached();
1111 }
1112 }
1113 return gen_shift(ctx, a, ext, f_tl, f_128);
1114 }
1115
1116 static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
1117 void (*func)(TCGv, TCGv))
1118 {
1119 TCGv dest = dest_gpr(ctx, a->rd);
1120 TCGv src1 = get_gpr(ctx, a->rs1, ext);
1121
1122 func(dest, src1);
1123
1124 gen_set_gpr(ctx, a->rd, dest);
1125 return true;
1126 }
1127
1128 static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
1129 void (*f_tl)(TCGv, TCGv),
1130 void (*f_32)(TCGv, TCGv))
1131 {
1132 int olen = get_olen(ctx);
1133
1134 if (olen != TARGET_LONG_BITS) {
1135 if (olen == 32) {
1136 f_tl = f_32;
1137 } else {
1138 g_assert_not_reached();
1139 }
1140 }
1141 return gen_unary(ctx, a, ext, f_tl);
1142 }
1143
1144 static bool gen_amo(DisasContext *ctx, arg_atomic *a,
1145 void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
1146 MemOp mop)
1147 {
1148 TCGv dest = dest_gpr(ctx, a->rd);
1149 TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
1150 MemOp size = mop & MO_SIZE;
1151
1152 mop |= ctx->mo_endianness;
1153 if (ctx->cfg_ptr->ext_zama16b && size >= MO_32) {
1154 mop |= MO_ATOM_WITHIN16;
1155 } else {
1156 mop |= MO_ALIGN;
1157 }
1158
1159 decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO);
1160 src1 = get_address(ctx, a->rs1, 0);
1161 func(dest, src1, src2, ctx->mem_idx, mop);
1162
1163 gen_set_gpr(ctx, a->rd, dest);
1164 return true;
1165 }
1166
1167 static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop)
1168 {
1169 TCGv dest = get_gpr(ctx, a->rd, EXT_NONE);
1170 TCGv src1 = get_address(ctx, a->rs1, 0);
1171 TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
1172
1173 mop |= ctx->mo_endianness;
1174 decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO);
1175 tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop);
1176
1177 gen_set_gpr(ctx, a->rd, dest);
1178 return true;
1179 }
1180
1181 static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
1182 {
1183 DisasContext *ctx = container_of(dcbase, DisasContext, base);
1184 CPUState *cpu = ctx->cs;
1185 CPURISCVState *env = cpu_env(cpu);
1186 MemOpIdx oi = make_memop_idx(MO_LEUL, cpu_mmu_index(cpu, true));
1187
1188 return cpu_ldl_code_mmu(env, pc, oi, 0);
1189 }
1190
1191 #define SS_MMU_INDEX(ctx) (ctx->mem_idx | MMU_IDX_SS_WRITE)
1192
1193 /* Include insn module translation function */
1194 #include "insn_trans/trans_rvi.c.inc"
1195 #include "insn_trans/trans_rvm.c.inc"
1196 #include "insn_trans/trans_rva.c.inc"
1197 #include "insn_trans/trans_rvf.c.inc"
1198 #include "insn_trans/trans_rvd.c.inc"
1199 #include "insn_trans/trans_rvh.c.inc"
1200 #include "insn_trans/trans_rvv.c.inc"
1201 #include "insn_trans/trans_rvb.c.inc"
1202 #include "insn_trans/trans_rvzicond.c.inc"
1203 #include "insn_trans/trans_rvzacas.c.inc"
1204 #include "insn_trans/trans_rvzabha.c.inc"
1205 #include "insn_trans/trans_rvzalasr.c.inc"
1206 #include "insn_trans/trans_rvzawrs.c.inc"
1207 #include "insn_trans/trans_rvzicbo.c.inc"
1208 #include "insn_trans/trans_rvzimop.c.inc"
1209 #include "insn_trans/trans_rvzfa.c.inc"
1210 #include "insn_trans/trans_rvzfh.c.inc"
1211 #include "insn_trans/trans_rvk.c.inc"
1212 #include "insn_trans/trans_rvvk.c.inc"
1213 #include "insn_trans/trans_privileged.c.inc"
1214 #include "insn_trans/trans_svinval.c.inc"
1215 #include "insn_trans/trans_rvbf16.c.inc"
1216 #include "decode-xthead.c.inc"
1217 #include "decode-xmips.c.inc"
1218 #include "decode-xlrbr.c.inc"
1219 #include "insn_trans/trans_xthead.c.inc"
1220 #include "insn_trans/trans_xventanacondops.c.inc"
1221 #include "insn_trans/trans_xmips.c.inc"
1222 #include "insn_trans/trans_xlrbr.c.inc"
1223
1224 /* Include the auto-generated decoder for 16 bit insn */
1225 #include "decode-insn16.c.inc"
1226 #include "insn_trans/trans_rvzce.c.inc"
1227 #include "insn_trans/trans_zilsd.c.inc"
1228 #include "insn_trans/trans_rvzcmop.c.inc"
1229 #include "insn_trans/trans_rvzicfiss.c.inc"
1230
1231 /* Include decoders for factored-out extensions */
1232 #include "decode-XVentanaCondOps.c.inc"
1233
1234 /* The specification allows for longer insns, but not supported by qemu. */
1235 #define MAX_INSN_LEN 4
1236
1237 const RISCVDecoder decoder_table[] = {
1238 { always_true_p, decode_insn32 },
1239 { has_xmips_p, decode_xmips},
1240 { has_xthead_p, decode_xthead},
1241 { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
1242 { has_xlrbr_p, decode_xlrbr},
1243 };
1244
1245 const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
1246
1247 static void decode_opc(CPURISCVState *env, DisasContext *ctx)
1248 {
1249 uint32_t opcode;
1250 bool pc_is_4byte_align = ((ctx->base.pc_next % 4) == 0);
1251
1252 ctx->virt_inst_excp = false;
1253 if (pc_is_4byte_align) {
1254 /*
1255 * Load 4 bytes at once to make instruction fetch atomically.
1256 *
1257 * Note: When pc is 4-byte aligned, 4-byte instruction wouldn't be
1258 * across pages. We could preload 4 bytes instruction no matter
1259 * real one is 2 or 4 bytes. Instruction preload wouldn't trigger
1260 * additional page fault.
1261 */
1262 opcode = translator_ldl_end(env, &ctx->base, ctx->base.pc_next,
1263 MO_LE);
1264 } else {
1265 /*
1266 * For unaligned pc, instruction preload may trigger additional
1267 * page fault so we only load 2 bytes here.
1268 */
1269 opcode = (uint32_t) translator_lduw_end(env, &ctx->base,
1270 ctx->base.pc_next,
1271 MO_LE);
1272 }
1273 ctx->ol = ctx->xl;
1274
1275 ctx->cur_insn_len = insn_len((uint16_t)opcode);
1276 /* Check for compressed insn */
1277 if (ctx->cur_insn_len == 2) {
1278 ctx->opcode = (uint16_t)opcode;
1279 /*
1280 * The Zca extension is added as way to refer to instructions in the C
1281 * extension that do not include the floating-point loads and stores
1282 */
1283 if ((has_ext(ctx, RVC) || ctx->cfg_ptr->ext_zca) &&
1284 decode_insn16(ctx, opcode)) {
1285 return;
1286 }
1287 } else {
1288 if (!pc_is_4byte_align) {
1289 /* Load last 2 bytes of instruction here */
1290 opcode = deposit32(opcode, 16, 16,
1291 translator_lduw_end(env, &ctx->base,
1292 ctx->base.pc_next + 2,
1293 MO_LE));
1294 }
1295 ctx->opcode = opcode;
1296
1297 for (guint i = 0; i < ctx->decoders->len; ++i) {
1298 riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
1299 if (func(ctx, opcode)) {
1300 return;
1301 }
1302 }
1303 }
1304
1305 gen_exception_illegal(ctx);
1306 }
1307
1308 static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
1309 {
1310 DisasContext *ctx = container_of(dcbase, DisasContext, base);
1311 CPURISCVState *env = cpu_env(cs);
1312 RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cs);
1313 RISCVCPU *cpu = RISCV_CPU(cs);
1314 uint32_t tb_flags = ctx->base.tb->flags;
1315 uint64_t ext_tb_flags = ctx->base.tb->cs_base;
1316
1317 ctx->pc_save = ctx->base.pc_first;
1318 ctx->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
1319 ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
1320 ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS);
1321 ctx->mstatus_vs = FIELD_EX32(tb_flags, TB_FLAGS, VS);
1322 ctx->priv_ver = env->priv_ver;
1323 ctx->virt_enabled = FIELD_EX32(tb_flags, TB_FLAGS, VIRT_ENABLED);
1324 ctx->misa_ext = env->misa_ext;
1325 ctx->frm = -1; /* unknown rounding mode */
1326 ctx->cfg_ptr = &(cpu->cfg);
1327 ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
1328 ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
1329 ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
1330 ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
1331 ctx->vma = FIELD_EX32(tb_flags, TB_FLAGS, VMA) && cpu->cfg.rvv_ma_all_1s;
1332 ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
1333 ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
1334 ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
1335 ctx->altfmt = FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, ALTFMT);
1336 ctx->misa_mxl_max = mcc->def->misa_mxl_max;
1337 ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
1338 ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
1339 ctx->cs = cs;
1340 if (get_xl(ctx) == MXL_RV32) {
1341 ctx->addr_xl = 32;
1342 ctx->addr_signed = false;
1343 } else {
1344 int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM);
1345 ctx->addr_xl = 64 - riscv_pm_get_pmlen(pm_pmm);
1346 ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND);
1347 }
1348 ctx->ztso = cpu->cfg.ext_ztso;
1349 ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
1350 ctx->bcfi_enabled = FIELD_EX32(tb_flags, TB_FLAGS, BCFI_ENABLED);
1351 ctx->fcfi_lp_expected = FIELD_EX32(tb_flags, TB_FLAGS, FCFI_LP_EXPECTED);
1352 ctx->fcfi_enabled = FIELD_EX32(tb_flags, TB_FLAGS, FCFI_ENABLED);
1353 ctx->zero = tcg_constant_tl(0);
1354 ctx->virt_inst_excp = false;
1355 ctx->decoders = cpu->decoders;
1356 ctx->mo_endianness = FIELD_EX64(ext_tb_flags, EXT_TB_FLAGS, BIG_ENDIAN)
1357 ? MO_BE : MO_LE;
1358 }
1359
1360 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
1361 {
1362 }
1363
1364 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
1365 {
1366 DisasContext *ctx = container_of(dcbase, DisasContext, base);
1367 target_ulong pc_next = ctx->base.pc_next;
1368
1369 if (tb_cflags(dcbase->tb) & CF_PCREL) {
1370 pc_next &= ~TARGET_PAGE_MASK;
1371 }
1372
1373 tcg_gen_insn_start(pc_next, 0, 0);
1374 ctx->insn_start_updated = false;
1375 }
1376
1377 static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
1378 {
1379 DisasContext *ctx = container_of(dcbase, DisasContext, base);
1380 CPURISCVState *env = cpu_env(cpu);
1381
1382 decode_opc(env, ctx);
1383 ctx->base.pc_next += ctx->cur_insn_len;
1384
1385 /*
1386 * If 'fcfi_lp_expected' is still true after processing the instruction,
1387 * then we did not see an 'lpad' instruction, and must raise an exception.
1388 * Insert code to raise the exception at the start of the insn; any other
1389 * code the insn may have emitted will be deleted as dead code following
1390 * the noreturn exception
1391 */
1392 if (ctx->fcfi_lp_expected) {
1393 /* Emit after insn_start, i.e. before the op following insn_start. */
1394 tcg_ctx->emit_before_op = QTAILQ_NEXT(ctx->base.insn_start, link);
1395 tcg_gen_st8_i32(tcg_constant_i32(RISCV_EXCP_SW_CHECK_FCFI_TVAL),
1396 tcg_env, offsetof(CPURISCVState, sw_check_code));
1397 gen_helper_raise_exception(tcg_env,
1398 tcg_constant_i32(RISCV_EXCP_SW_CHECK));
1399 tcg_ctx->emit_before_op = NULL;
1400 ctx->base.is_jmp = DISAS_NORETURN;
1401 }
1402
1403 /* Only the first insn within a TB is allowed to cross a page boundary. */
1404 if (ctx->base.is_jmp == DISAS_NEXT) {
1405 if (ctx->itrigger || !translator_is_same_page(&ctx->base, ctx->base.pc_next)) {
1406 ctx->base.is_jmp = DISAS_TOO_MANY;
1407 } else {
1408 unsigned page_ofs = ctx->base.pc_next & ~TARGET_PAGE_MASK;
1409
1410 if (page_ofs > TARGET_PAGE_SIZE - MAX_INSN_LEN) {
1411 uint16_t next_insn =
1412 translator_lduw_end(env, &ctx->base, ctx->base.pc_next,
1413 MO_LE);
1414 int len = insn_len(next_insn);
1415
1416 if (!translator_is_same_page(&ctx->base, ctx->base.pc_next + len - 1)) {
1417 ctx->base.is_jmp = DISAS_TOO_MANY;
1418 }
1419 }
1420 }
1421 }
1422 }
1423
1424 static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
1425 {
1426 DisasContext *ctx = container_of(dcbase, DisasContext, base);
1427
1428 switch (ctx->base.is_jmp) {
1429 case DISAS_TOO_MANY:
1430 gen_goto_tb(ctx, 0, 0);
1431 break;
1432 case DISAS_NORETURN:
1433 break;
1434 default:
1435 g_assert_not_reached();
1436 }
1437 }
1438
1439 static const TranslatorOps riscv_tr_ops = {
1440 .init_disas_context = riscv_tr_init_disas_context,
1441 .tb_start = riscv_tr_tb_start,
1442 .insn_start = riscv_tr_insn_start,
1443 .translate_insn = riscv_tr_translate_insn,
1444 .tb_stop = riscv_tr_tb_stop,
1445 };
1446
1447 void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
1448 int *max_insns, vaddr pc, void *host_pc)
1449 {
1450 DisasContext ctx;
1451
1452 translator_loop(cs, tb, max_insns, pc, host_pc, &riscv_tr_ops, &ctx.base,
1453 TCG_TYPE_VA);
1454 }
1455
1456 void riscv_translate_init(void)
1457 {
1458 int i;
1459
1460 /*
1461 * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
1462 * Use the gen_set_gpr and get_gpr helper functions when accessing regs,
1463 * unless you specifically block reads/writes to reg 0.
1464 */
1465 cpu_gpr[0] = NULL;
1466 cpu_gprh[0] = NULL;
1467 /*
1468 * Be careful with big endian hosts when mapping 64-bit CPUArchState fields
1469 * to 32-bit TCGv globals. An offset of 4 bytes is applied so the least
1470 * significant bytes are correctly written to.
1471 */
1472 #if HOST_BIG_ENDIAN && !defined(TARGET_RISCV64)
1473 size_t field_offset = 4;
1474 #else
1475 size_t field_offset = 0;
1476 #endif
1477
1478 /* 32 bits in size, no offset needed */
1479 size_t vl_offset = offsetof(CPURISCVState, vl);
1480 size_t vstart_offset = offsetof(CPURISCVState, vstart);
1481 /* 64 bits in size mapped to TCGv, needs offset */
1482 size_t pc_offset = offsetof(CPURISCVState, pc) + field_offset;
1483 size_t res_offset = offsetof(CPURISCVState, load_res) + field_offset;
1484 size_t val_offset = offsetof(CPURISCVState, load_val) + field_offset;
1485
1486 for (i = 1; i < 32; i++) {
1487 cpu_gpr[i] = tcg_global_mem_new(tcg_env,
1488 offsetof(CPURISCVState, gpr[i]) + field_offset,
1489 riscv_int_regnames[i]);
1490 cpu_gprh[i] = tcg_global_mem_new(tcg_env,
1491 offsetof(CPURISCVState, gprh[i]) + field_offset,
1492 riscv_int_regnamesh[i]);
1493 }
1494
1495 for (i = 0; i < 32; i++) {
1496 cpu_fpr[i] = tcg_global_mem_new_i64(tcg_env,
1497 offsetof(CPURISCVState, fpr[i]), riscv_fpr_regnames[i]);
1498 }
1499
1500 cpu_pc = tcg_global_mem_new(tcg_env, pc_offset, "pc");
1501 cpu_vl = tcg_global_mem_new_i32(tcg_env, vl_offset, "vl");
1502 cpu_vstart = tcg_global_mem_new_i32(tcg_env, vstart_offset, "vstart");
1503 load_res = tcg_global_mem_new(tcg_env, res_offset, "load_res");
1504 load_val = tcg_global_mem_new(tcg_env, val_offset, "load_val");
1505 }