1/* 2 * RISC-V translation routines for the RV64D Standard Extension. 3 * 4 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu 5 * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de 6 * Bastian Koppelmann, kbastian@mail.uni-paderborn.de 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms and conditions of the GNU General Public License, 10 * version 2 or later, as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along with 18 * this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#define REQUIRE_ZDINX_OR_D(ctx) do { \ 22 if (!ctx->cfg_ptr->ext_zdinx) { \ 23 REQUIRE_EXT(ctx, RVD); \ 24 } \ 25} while (0) 26 27#define REQUIRE_EVEN(ctx, reg) do { \ 28 if (ctx->cfg_ptr->ext_zdinx && (get_xl(ctx) == MXL_RV32) && \ 29 ((reg) & 0x1)) { \ 30 return false; \ 31 } \ 32} while (0) 33 34#define REQUIRE_ZCD_OR_DC(ctx) do { \ 35 if (!ctx->cfg_ptr->ext_zcd) { \ 36 if (!has_ext(ctx, RVD) || !has_ext(ctx, RVC)) { \ 37 return false; \ 38 } \ 39 } \ 40} while (0) 41 42static bool trans_fld(DisasContext *ctx, arg_fld *a) 43{ 44 TCGv addr; 45 MemOp memop = MO_TEUQ; 46 47 REQUIRE_FPU; 48 REQUIRE_EXT(ctx, RVD); 49 50 if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) { 51 memop |= MO_ATOM_WITHIN16; 52 } 53 54 decode_save_opc(ctx); 55 addr = get_address(ctx, a->rs1, a->imm); 56 tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, memop); 57 58 mark_fs_dirty(ctx); 59 return true; 60} 61 62static bool trans_fsd(DisasContext *ctx, arg_fsd *a) 63{ 64 TCGv addr; 65 MemOp memop = MO_TEUQ; 66 67 REQUIRE_FPU; 68 REQUIRE_EXT(ctx, RVD); 69 70 if (ctx->cfg_ptr->ext_zama16b && (ctx->cur_insn_len != 2)) { 71 memop |= MO_ATOM_WITHIN16; 72 } 73 74 decode_save_opc(ctx); 75 addr = get_address(ctx, a->rs1, a->imm); 76 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, memop); 77 return true; 78} 79 80static bool trans_c_fld(DisasContext *ctx, arg_fld *a) 81{ 82 REQUIRE_ZCD_OR_DC(ctx); 83 return trans_fld(ctx, a); 84} 85 86static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a) 87{ 88 REQUIRE_ZCD_OR_DC(ctx); 89 return trans_fsd(ctx, a); 90} 91 92static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a) 93{ 94 REQUIRE_FPU; 95 REQUIRE_ZDINX_OR_D(ctx); 96 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 97 98 TCGv_i64 dest = dest_fpr(ctx, a->rd); 99 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 100 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 101 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 102 103 gen_set_rm(ctx, a->rm); 104 gen_helper_fmadd_d(dest, tcg_env, src1, src2, src3); 105 gen_set_fpr_d(ctx, a->rd, dest); 106 mark_fs_dirty(ctx); 107 return true; 108} 109 110static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a) 111{ 112 REQUIRE_FPU; 113 REQUIRE_ZDINX_OR_D(ctx); 114 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 115 116 TCGv_i64 dest = dest_fpr(ctx, a->rd); 117 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 118 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 119 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 120 121 gen_set_rm(ctx, a->rm); 122 gen_helper_fmsub_d(dest, tcg_env, src1, src2, src3); 123 gen_set_fpr_d(ctx, a->rd, dest); 124 mark_fs_dirty(ctx); 125 return true; 126} 127 128static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a) 129{ 130 REQUIRE_FPU; 131 REQUIRE_ZDINX_OR_D(ctx); 132 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 133 134 TCGv_i64 dest = dest_fpr(ctx, a->rd); 135 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 136 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 137 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 138 139 gen_set_rm(ctx, a->rm); 140 gen_helper_fnmsub_d(dest, tcg_env, src1, src2, src3); 141 gen_set_fpr_d(ctx, a->rd, dest); 142 mark_fs_dirty(ctx); 143 return true; 144} 145 146static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a) 147{ 148 REQUIRE_FPU; 149 REQUIRE_ZDINX_OR_D(ctx); 150 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 151 152 TCGv_i64 dest = dest_fpr(ctx, a->rd); 153 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 154 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 155 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 156 157 gen_set_rm(ctx, a->rm); 158 gen_helper_fnmadd_d(dest, tcg_env, src1, src2, src3); 159 gen_set_fpr_d(ctx, a->rd, dest); 160 mark_fs_dirty(ctx); 161 return true; 162} 163 164static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a) 165{ 166 REQUIRE_FPU; 167 REQUIRE_ZDINX_OR_D(ctx); 168 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 169 170 TCGv_i64 dest = dest_fpr(ctx, a->rd); 171 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 172 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 173 174 gen_set_rm(ctx, a->rm); 175 gen_helper_fadd_d(dest, tcg_env, src1, src2); 176 gen_set_fpr_d(ctx, a->rd, dest); 177 mark_fs_dirty(ctx); 178 return true; 179} 180 181static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a) 182{ 183 REQUIRE_FPU; 184 REQUIRE_ZDINX_OR_D(ctx); 185 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 186 187 TCGv_i64 dest = dest_fpr(ctx, a->rd); 188 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 189 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 190 191 gen_set_rm(ctx, a->rm); 192 gen_helper_fsub_d(dest, tcg_env, src1, src2); 193 gen_set_fpr_d(ctx, a->rd, dest); 194 mark_fs_dirty(ctx); 195 return true; 196} 197 198static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a) 199{ 200 REQUIRE_FPU; 201 REQUIRE_ZDINX_OR_D(ctx); 202 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 203 204 TCGv_i64 dest = dest_fpr(ctx, a->rd); 205 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 206 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 207 208 gen_set_rm(ctx, a->rm); 209 gen_helper_fmul_d(dest, tcg_env, src1, src2); 210 gen_set_fpr_d(ctx, a->rd, dest); 211 mark_fs_dirty(ctx); 212 return true; 213} 214 215static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a) 216{ 217 REQUIRE_FPU; 218 REQUIRE_ZDINX_OR_D(ctx); 219 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 220 221 TCGv_i64 dest = dest_fpr(ctx, a->rd); 222 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 223 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 224 225 gen_set_rm(ctx, a->rm); 226 gen_helper_fdiv_d(dest, tcg_env, src1, src2); 227 gen_set_fpr_d(ctx, a->rd, dest); 228 mark_fs_dirty(ctx); 229 return true; 230} 231 232static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a) 233{ 234 REQUIRE_FPU; 235 REQUIRE_ZDINX_OR_D(ctx); 236 REQUIRE_EVEN(ctx, a->rd | a->rs1); 237 238 TCGv_i64 dest = dest_fpr(ctx, a->rd); 239 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 240 241 gen_set_rm(ctx, a->rm); 242 gen_helper_fsqrt_d(dest, tcg_env, src1); 243 gen_set_fpr_d(ctx, a->rd, dest); 244 mark_fs_dirty(ctx); 245 return true; 246} 247 248static bool trans_fsgnj_d(DisasContext *ctx, arg_fsgnj_d *a) 249{ 250 REQUIRE_FPU; 251 REQUIRE_ZDINX_OR_D(ctx); 252 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 253 254 TCGv_i64 dest = dest_fpr(ctx, a->rd); 255 if (a->rs1 == a->rs2) { /* FMOV */ 256 dest = get_fpr_d(ctx, a->rs1); 257 } else { 258 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 259 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 260 tcg_gen_deposit_i64(dest, src2, src1, 0, 63); 261 } 262 gen_set_fpr_d(ctx, a->rd, dest); 263 mark_fs_dirty(ctx); 264 return true; 265} 266 267static bool trans_fsgnjn_d(DisasContext *ctx, arg_fsgnjn_d *a) 268{ 269 REQUIRE_FPU; 270 REQUIRE_ZDINX_OR_D(ctx); 271 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 272 273 TCGv_i64 dest = dest_fpr(ctx, a->rd); 274 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 275 276 if (a->rs1 == a->rs2) { /* FNEG */ 277 tcg_gen_xori_i64(dest, src1, INT64_MIN); 278 } else { 279 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 280 TCGv_i64 t0 = tcg_temp_new_i64(); 281 tcg_gen_not_i64(t0, src2); 282 tcg_gen_deposit_i64(dest, t0, src1, 0, 63); 283 } 284 gen_set_fpr_d(ctx, a->rd, dest); 285 mark_fs_dirty(ctx); 286 return true; 287} 288 289static bool trans_fsgnjx_d(DisasContext *ctx, arg_fsgnjx_d *a) 290{ 291 REQUIRE_FPU; 292 REQUIRE_ZDINX_OR_D(ctx); 293 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 294 295 TCGv_i64 dest = dest_fpr(ctx, a->rd); 296 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 297 298 if (a->rs1 == a->rs2) { /* FABS */ 299 tcg_gen_andi_i64(dest, src1, ~INT64_MIN); 300 } else { 301 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 302 TCGv_i64 t0 = tcg_temp_new_i64(); 303 tcg_gen_andi_i64(t0, src2, INT64_MIN); 304 tcg_gen_xor_i64(dest, src1, t0); 305 } 306 gen_set_fpr_d(ctx, a->rd, dest); 307 mark_fs_dirty(ctx); 308 return true; 309} 310 311static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a) 312{ 313 REQUIRE_FPU; 314 REQUIRE_ZDINX_OR_D(ctx); 315 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 316 317 TCGv_i64 dest = dest_fpr(ctx, a->rd); 318 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 319 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 320 321 gen_helper_fmin_d(dest, tcg_env, src1, src2); 322 gen_set_fpr_d(ctx, a->rd, dest); 323 mark_fs_dirty(ctx); 324 return true; 325} 326 327static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a) 328{ 329 REQUIRE_FPU; 330 REQUIRE_ZDINX_OR_D(ctx); 331 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 332 333 TCGv_i64 dest = dest_fpr(ctx, a->rd); 334 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 335 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 336 337 gen_helper_fmax_d(dest, tcg_env, src1, src2); 338 gen_set_fpr_d(ctx, a->rd, dest); 339 mark_fs_dirty(ctx); 340 return true; 341} 342 343static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a) 344{ 345 REQUIRE_FPU; 346 REQUIRE_ZDINX_OR_D(ctx); 347 REQUIRE_EVEN(ctx, a->rs1); 348 349 TCGv_i64 dest = dest_fpr(ctx, a->rd); 350 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 351 352 gen_set_rm(ctx, a->rm); 353 gen_helper_fcvt_s_d(dest, tcg_env, src1); 354 gen_set_fpr_hs(ctx, a->rd, dest); 355 mark_fs_dirty(ctx); 356 return true; 357} 358 359static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a) 360{ 361 REQUIRE_FPU; 362 REQUIRE_ZDINX_OR_D(ctx); 363 REQUIRE_EVEN(ctx, a->rd); 364 365 TCGv_i64 dest = dest_fpr(ctx, a->rd); 366 TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 367 368 gen_set_rm(ctx, a->rm); 369 gen_helper_fcvt_d_s(dest, tcg_env, src1); 370 gen_set_fpr_d(ctx, a->rd, dest); 371 mark_fs_dirty(ctx); 372 return true; 373} 374 375static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a) 376{ 377 REQUIRE_FPU; 378 REQUIRE_ZDINX_OR_D(ctx); 379 REQUIRE_EVEN(ctx, a->rs1 | a->rs2); 380 381 TCGv dest = dest_gpr(ctx, a->rd); 382 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 383 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 384 385 gen_helper_feq_d(dest, tcg_env, src1, src2); 386 gen_set_gpr(ctx, a->rd, dest); 387 return true; 388} 389 390static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a) 391{ 392 REQUIRE_FPU; 393 REQUIRE_ZDINX_OR_D(ctx); 394 REQUIRE_EVEN(ctx, a->rs1 | a->rs2); 395 396 TCGv dest = dest_gpr(ctx, a->rd); 397 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 398 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 399 400 gen_helper_flt_d(dest, tcg_env, src1, src2); 401 gen_set_gpr(ctx, a->rd, dest); 402 return true; 403} 404 405static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a) 406{ 407 REQUIRE_FPU; 408 REQUIRE_ZDINX_OR_D(ctx); 409 REQUIRE_EVEN(ctx, a->rs1 | a->rs2); 410 411 TCGv dest = dest_gpr(ctx, a->rd); 412 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 413 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 414 415 gen_helper_fle_d(dest, tcg_env, src1, src2); 416 gen_set_gpr(ctx, a->rd, dest); 417 return true; 418} 419 420static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a) 421{ 422 REQUIRE_FPU; 423 REQUIRE_ZDINX_OR_D(ctx); 424 REQUIRE_EVEN(ctx, a->rs1); 425 426 TCGv dest = dest_gpr(ctx, a->rd); 427 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 428 429 gen_helper_fclass_d(dest, src1); 430 gen_set_gpr(ctx, a->rd, dest); 431 return true; 432} 433 434static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a) 435{ 436 REQUIRE_FPU; 437 REQUIRE_ZDINX_OR_D(ctx); 438 REQUIRE_EVEN(ctx, a->rs1); 439 440 TCGv dest = dest_gpr(ctx, a->rd); 441 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 442 443 gen_set_rm(ctx, a->rm); 444 gen_helper_fcvt_w_d(dest, tcg_env, src1); 445 gen_set_gpr(ctx, a->rd, dest); 446 return true; 447} 448 449static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a) 450{ 451 REQUIRE_FPU; 452 REQUIRE_ZDINX_OR_D(ctx); 453 REQUIRE_EVEN(ctx, a->rs1); 454 455 TCGv dest = dest_gpr(ctx, a->rd); 456 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 457 458 gen_set_rm(ctx, a->rm); 459 gen_helper_fcvt_wu_d(dest, tcg_env, src1); 460 gen_set_gpr(ctx, a->rd, dest); 461 return true; 462} 463 464static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a) 465{ 466 REQUIRE_FPU; 467 REQUIRE_ZDINX_OR_D(ctx); 468 REQUIRE_EVEN(ctx, a->rd); 469 470 TCGv_i64 dest = dest_fpr(ctx, a->rd); 471 TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN); 472 473 gen_set_rm(ctx, a->rm); 474 gen_helper_fcvt_d_w(dest, tcg_env, src); 475 gen_set_fpr_d(ctx, a->rd, dest); 476 477 mark_fs_dirty(ctx); 478 return true; 479} 480 481static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a) 482{ 483 REQUIRE_FPU; 484 REQUIRE_ZDINX_OR_D(ctx); 485 REQUIRE_EVEN(ctx, a->rd); 486 487 TCGv_i64 dest = dest_fpr(ctx, a->rd); 488 TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO); 489 490 gen_set_rm(ctx, a->rm); 491 gen_helper_fcvt_d_wu(dest, tcg_env, src); 492 gen_set_fpr_d(ctx, a->rd, dest); 493 494 mark_fs_dirty(ctx); 495 return true; 496} 497 498static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a) 499{ 500 REQUIRE_64BIT(ctx); 501 REQUIRE_FPU; 502 REQUIRE_ZDINX_OR_D(ctx); 503 REQUIRE_EVEN(ctx, a->rs1); 504 505 TCGv dest = dest_gpr(ctx, a->rd); 506 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 507 508 gen_set_rm(ctx, a->rm); 509 gen_helper_fcvt_l_d(dest, tcg_env, src1); 510 gen_set_gpr(ctx, a->rd, dest); 511 return true; 512} 513 514static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a) 515{ 516 REQUIRE_64BIT(ctx); 517 REQUIRE_FPU; 518 REQUIRE_ZDINX_OR_D(ctx); 519 REQUIRE_EVEN(ctx, a->rs1); 520 521 TCGv dest = dest_gpr(ctx, a->rd); 522 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 523 524 gen_set_rm(ctx, a->rm); 525 gen_helper_fcvt_lu_d(dest, tcg_env, src1); 526 gen_set_gpr(ctx, a->rd, dest); 527 return true; 528} 529 530static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a) 531{ 532 REQUIRE_64BIT(ctx); 533 REQUIRE_FPU; 534 REQUIRE_EXT(ctx, RVD); 535 536#ifdef TARGET_RISCV64 537 gen_set_gpr(ctx, a->rd, cpu_fpr[a->rs1]); 538 return true; 539#else 540 qemu_build_not_reached(); 541#endif 542} 543 544static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a) 545{ 546 REQUIRE_64BIT(ctx); 547 REQUIRE_FPU; 548 REQUIRE_ZDINX_OR_D(ctx); 549 REQUIRE_EVEN(ctx, a->rd); 550 551 TCGv_i64 dest = dest_fpr(ctx, a->rd); 552 TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN); 553 554 gen_set_rm(ctx, a->rm); 555 gen_helper_fcvt_d_l(dest, tcg_env, src); 556 gen_set_fpr_d(ctx, a->rd, dest); 557 558 mark_fs_dirty(ctx); 559 return true; 560} 561 562static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a) 563{ 564 REQUIRE_64BIT(ctx); 565 REQUIRE_FPU; 566 REQUIRE_ZDINX_OR_D(ctx); 567 REQUIRE_EVEN(ctx, a->rd); 568 569 TCGv_i64 dest = dest_fpr(ctx, a->rd); 570 TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO); 571 572 gen_set_rm(ctx, a->rm); 573 gen_helper_fcvt_d_lu(dest, tcg_env, src); 574 gen_set_fpr_d(ctx, a->rd, dest); 575 576 mark_fs_dirty(ctx); 577 return true; 578} 579 580static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a) 581{ 582 REQUIRE_64BIT(ctx); 583 REQUIRE_FPU; 584 REQUIRE_EXT(ctx, RVD); 585 586#ifdef TARGET_RISCV64 587 tcg_gen_mov_tl(cpu_fpr[a->rd], get_gpr(ctx, a->rs1, EXT_NONE)); 588 mark_fs_dirty(ctx); 589 return true; 590#else 591 qemu_build_not_reached(); 592#endif 593} 594