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