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 46 REQUIRE_FPU; 47 REQUIRE_EXT(ctx, RVD); 48 49 decode_save_opc(ctx); 50 addr = get_address(ctx, a->rs1, a->imm); 51 tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ); 52 53 mark_fs_dirty(ctx); 54 return true; 55} 56 57static bool trans_fsd(DisasContext *ctx, arg_fsd *a) 58{ 59 TCGv addr; 60 61 REQUIRE_FPU; 62 REQUIRE_EXT(ctx, RVD); 63 64 decode_save_opc(ctx); 65 addr = get_address(ctx, a->rs1, a->imm); 66 tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ); 67 return true; 68} 69 70static bool trans_c_fld(DisasContext *ctx, arg_fld *a) 71{ 72 REQUIRE_ZCD_OR_DC(ctx); 73 return trans_fld(ctx, a); 74} 75 76static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a) 77{ 78 REQUIRE_ZCD_OR_DC(ctx); 79 return trans_fsd(ctx, a); 80} 81 82static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a) 83{ 84 REQUIRE_FPU; 85 REQUIRE_ZDINX_OR_D(ctx); 86 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 87 88 TCGv_i64 dest = dest_fpr(ctx, a->rd); 89 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 90 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 91 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 92 93 gen_set_rm(ctx, a->rm); 94 gen_helper_fmadd_d(dest, tcg_env, src1, src2, src3); 95 gen_set_fpr_d(ctx, a->rd, dest); 96 mark_fs_dirty(ctx); 97 return true; 98} 99 100static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a) 101{ 102 REQUIRE_FPU; 103 REQUIRE_ZDINX_OR_D(ctx); 104 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 105 106 TCGv_i64 dest = dest_fpr(ctx, a->rd); 107 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 108 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 109 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 110 111 gen_set_rm(ctx, a->rm); 112 gen_helper_fmsub_d(dest, tcg_env, src1, src2, src3); 113 gen_set_fpr_d(ctx, a->rd, dest); 114 mark_fs_dirty(ctx); 115 return true; 116} 117 118static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a) 119{ 120 REQUIRE_FPU; 121 REQUIRE_ZDINX_OR_D(ctx); 122 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 123 124 TCGv_i64 dest = dest_fpr(ctx, a->rd); 125 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 126 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 127 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 128 129 gen_set_rm(ctx, a->rm); 130 gen_helper_fnmsub_d(dest, tcg_env, src1, src2, src3); 131 gen_set_fpr_d(ctx, a->rd, dest); 132 mark_fs_dirty(ctx); 133 return true; 134} 135 136static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a) 137{ 138 REQUIRE_FPU; 139 REQUIRE_ZDINX_OR_D(ctx); 140 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2 | a->rs3); 141 142 TCGv_i64 dest = dest_fpr(ctx, a->rd); 143 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 144 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 145 TCGv_i64 src3 = get_fpr_d(ctx, a->rs3); 146 147 gen_set_rm(ctx, a->rm); 148 gen_helper_fnmadd_d(dest, tcg_env, src1, src2, src3); 149 gen_set_fpr_d(ctx, a->rd, dest); 150 mark_fs_dirty(ctx); 151 return true; 152} 153 154static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a) 155{ 156 REQUIRE_FPU; 157 REQUIRE_ZDINX_OR_D(ctx); 158 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 159 160 TCGv_i64 dest = dest_fpr(ctx, a->rd); 161 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 162 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 163 164 gen_set_rm(ctx, a->rm); 165 gen_helper_fadd_d(dest, tcg_env, src1, src2); 166 gen_set_fpr_d(ctx, a->rd, dest); 167 mark_fs_dirty(ctx); 168 return true; 169} 170 171static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a) 172{ 173 REQUIRE_FPU; 174 REQUIRE_ZDINX_OR_D(ctx); 175 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 176 177 TCGv_i64 dest = dest_fpr(ctx, a->rd); 178 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 179 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 180 181 gen_set_rm(ctx, a->rm); 182 gen_helper_fsub_d(dest, tcg_env, src1, src2); 183 gen_set_fpr_d(ctx, a->rd, dest); 184 mark_fs_dirty(ctx); 185 return true; 186} 187 188static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a) 189{ 190 REQUIRE_FPU; 191 REQUIRE_ZDINX_OR_D(ctx); 192 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 193 194 TCGv_i64 dest = dest_fpr(ctx, a->rd); 195 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 196 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 197 198 gen_set_rm(ctx, a->rm); 199 gen_helper_fmul_d(dest, tcg_env, src1, src2); 200 gen_set_fpr_d(ctx, a->rd, dest); 201 mark_fs_dirty(ctx); 202 return true; 203} 204 205static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a) 206{ 207 REQUIRE_FPU; 208 REQUIRE_ZDINX_OR_D(ctx); 209 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 210 211 TCGv_i64 dest = dest_fpr(ctx, a->rd); 212 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 213 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 214 215 gen_set_rm(ctx, a->rm); 216 gen_helper_fdiv_d(dest, tcg_env, src1, src2); 217 gen_set_fpr_d(ctx, a->rd, dest); 218 mark_fs_dirty(ctx); 219 return true; 220} 221 222static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a) 223{ 224 REQUIRE_FPU; 225 REQUIRE_ZDINX_OR_D(ctx); 226 REQUIRE_EVEN(ctx, a->rd | a->rs1); 227 228 TCGv_i64 dest = dest_fpr(ctx, a->rd); 229 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 230 231 gen_set_rm(ctx, a->rm); 232 gen_helper_fsqrt_d(dest, tcg_env, src1); 233 gen_set_fpr_d(ctx, a->rd, dest); 234 mark_fs_dirty(ctx); 235 return true; 236} 237 238static bool trans_fsgnj_d(DisasContext *ctx, arg_fsgnj_d *a) 239{ 240 REQUIRE_FPU; 241 REQUIRE_ZDINX_OR_D(ctx); 242 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 243 244 TCGv_i64 dest = dest_fpr(ctx, a->rd); 245 if (a->rs1 == a->rs2) { /* FMOV */ 246 dest = get_fpr_d(ctx, a->rs1); 247 } else { 248 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 249 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 250 tcg_gen_deposit_i64(dest, src2, src1, 0, 63); 251 } 252 gen_set_fpr_d(ctx, a->rd, dest); 253 mark_fs_dirty(ctx); 254 return true; 255} 256 257static bool trans_fsgnjn_d(DisasContext *ctx, arg_fsgnjn_d *a) 258{ 259 REQUIRE_FPU; 260 REQUIRE_ZDINX_OR_D(ctx); 261 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 262 263 TCGv_i64 dest = dest_fpr(ctx, a->rd); 264 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 265 266 if (a->rs1 == a->rs2) { /* FNEG */ 267 tcg_gen_xori_i64(dest, src1, INT64_MIN); 268 } else { 269 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 270 TCGv_i64 t0 = tcg_temp_new_i64(); 271 tcg_gen_not_i64(t0, src2); 272 tcg_gen_deposit_i64(dest, t0, src1, 0, 63); 273 } 274 gen_set_fpr_d(ctx, a->rd, dest); 275 mark_fs_dirty(ctx); 276 return true; 277} 278 279static bool trans_fsgnjx_d(DisasContext *ctx, arg_fsgnjx_d *a) 280{ 281 REQUIRE_FPU; 282 REQUIRE_ZDINX_OR_D(ctx); 283 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 284 285 TCGv_i64 dest = dest_fpr(ctx, a->rd); 286 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 287 288 if (a->rs1 == a->rs2) { /* FABS */ 289 tcg_gen_andi_i64(dest, src1, ~INT64_MIN); 290 } else { 291 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 292 TCGv_i64 t0 = tcg_temp_new_i64(); 293 tcg_gen_andi_i64(t0, src2, INT64_MIN); 294 tcg_gen_xor_i64(dest, src1, t0); 295 } 296 gen_set_fpr_d(ctx, a->rd, dest); 297 mark_fs_dirty(ctx); 298 return true; 299} 300 301static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a) 302{ 303 REQUIRE_FPU; 304 REQUIRE_ZDINX_OR_D(ctx); 305 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 306 307 TCGv_i64 dest = dest_fpr(ctx, a->rd); 308 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 309 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 310 311 gen_helper_fmin_d(dest, tcg_env, src1, src2); 312 gen_set_fpr_d(ctx, a->rd, dest); 313 mark_fs_dirty(ctx); 314 return true; 315} 316 317static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a) 318{ 319 REQUIRE_FPU; 320 REQUIRE_ZDINX_OR_D(ctx); 321 REQUIRE_EVEN(ctx, a->rd | a->rs1 | a->rs2); 322 323 TCGv_i64 dest = dest_fpr(ctx, a->rd); 324 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 325 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 326 327 gen_helper_fmax_d(dest, tcg_env, src1, src2); 328 gen_set_fpr_d(ctx, a->rd, dest); 329 mark_fs_dirty(ctx); 330 return true; 331} 332 333static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a) 334{ 335 REQUIRE_FPU; 336 REQUIRE_ZDINX_OR_D(ctx); 337 REQUIRE_EVEN(ctx, a->rs1); 338 339 TCGv_i64 dest = dest_fpr(ctx, a->rd); 340 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 341 342 gen_set_rm(ctx, a->rm); 343 gen_helper_fcvt_s_d(dest, tcg_env, src1); 344 gen_set_fpr_hs(ctx, a->rd, dest); 345 mark_fs_dirty(ctx); 346 return true; 347} 348 349static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a) 350{ 351 REQUIRE_FPU; 352 REQUIRE_ZDINX_OR_D(ctx); 353 REQUIRE_EVEN(ctx, a->rd); 354 355 TCGv_i64 dest = dest_fpr(ctx, a->rd); 356 TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); 357 358 gen_set_rm(ctx, a->rm); 359 gen_helper_fcvt_d_s(dest, tcg_env, src1); 360 gen_set_fpr_d(ctx, a->rd, dest); 361 mark_fs_dirty(ctx); 362 return true; 363} 364 365static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a) 366{ 367 REQUIRE_FPU; 368 REQUIRE_ZDINX_OR_D(ctx); 369 REQUIRE_EVEN(ctx, a->rs1 | a->rs2); 370 371 TCGv dest = dest_gpr(ctx, a->rd); 372 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 373 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 374 375 gen_helper_feq_d(dest, tcg_env, src1, src2); 376 gen_set_gpr(ctx, a->rd, dest); 377 return true; 378} 379 380static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a) 381{ 382 REQUIRE_FPU; 383 REQUIRE_ZDINX_OR_D(ctx); 384 REQUIRE_EVEN(ctx, a->rs1 | a->rs2); 385 386 TCGv dest = dest_gpr(ctx, a->rd); 387 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 388 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 389 390 gen_helper_flt_d(dest, tcg_env, src1, src2); 391 gen_set_gpr(ctx, a->rd, dest); 392 return true; 393} 394 395static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a) 396{ 397 REQUIRE_FPU; 398 REQUIRE_ZDINX_OR_D(ctx); 399 REQUIRE_EVEN(ctx, a->rs1 | a->rs2); 400 401 TCGv dest = dest_gpr(ctx, a->rd); 402 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 403 TCGv_i64 src2 = get_fpr_d(ctx, a->rs2); 404 405 gen_helper_fle_d(dest, tcg_env, src1, src2); 406 gen_set_gpr(ctx, a->rd, dest); 407 return true; 408} 409 410static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a) 411{ 412 REQUIRE_FPU; 413 REQUIRE_ZDINX_OR_D(ctx); 414 REQUIRE_EVEN(ctx, a->rs1); 415 416 TCGv dest = dest_gpr(ctx, a->rd); 417 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 418 419 gen_helper_fclass_d(dest, src1); 420 gen_set_gpr(ctx, a->rd, dest); 421 return true; 422} 423 424static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a) 425{ 426 REQUIRE_FPU; 427 REQUIRE_ZDINX_OR_D(ctx); 428 REQUIRE_EVEN(ctx, a->rs1); 429 430 TCGv dest = dest_gpr(ctx, a->rd); 431 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 432 433 gen_set_rm(ctx, a->rm); 434 gen_helper_fcvt_w_d(dest, tcg_env, src1); 435 gen_set_gpr(ctx, a->rd, dest); 436 return true; 437} 438 439static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a) 440{ 441 REQUIRE_FPU; 442 REQUIRE_ZDINX_OR_D(ctx); 443 REQUIRE_EVEN(ctx, a->rs1); 444 445 TCGv dest = dest_gpr(ctx, a->rd); 446 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 447 448 gen_set_rm(ctx, a->rm); 449 gen_helper_fcvt_wu_d(dest, tcg_env, src1); 450 gen_set_gpr(ctx, a->rd, dest); 451 return true; 452} 453 454static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a) 455{ 456 REQUIRE_FPU; 457 REQUIRE_ZDINX_OR_D(ctx); 458 REQUIRE_EVEN(ctx, a->rd); 459 460 TCGv_i64 dest = dest_fpr(ctx, a->rd); 461 TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN); 462 463 gen_set_rm(ctx, a->rm); 464 gen_helper_fcvt_d_w(dest, tcg_env, src); 465 gen_set_fpr_d(ctx, a->rd, dest); 466 467 mark_fs_dirty(ctx); 468 return true; 469} 470 471static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a) 472{ 473 REQUIRE_FPU; 474 REQUIRE_ZDINX_OR_D(ctx); 475 REQUIRE_EVEN(ctx, a->rd); 476 477 TCGv_i64 dest = dest_fpr(ctx, a->rd); 478 TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO); 479 480 gen_set_rm(ctx, a->rm); 481 gen_helper_fcvt_d_wu(dest, tcg_env, src); 482 gen_set_fpr_d(ctx, a->rd, dest); 483 484 mark_fs_dirty(ctx); 485 return true; 486} 487 488static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a) 489{ 490 REQUIRE_64BIT(ctx); 491 REQUIRE_FPU; 492 REQUIRE_ZDINX_OR_D(ctx); 493 REQUIRE_EVEN(ctx, a->rs1); 494 495 TCGv dest = dest_gpr(ctx, a->rd); 496 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 497 498 gen_set_rm(ctx, a->rm); 499 gen_helper_fcvt_l_d(dest, tcg_env, src1); 500 gen_set_gpr(ctx, a->rd, dest); 501 return true; 502} 503 504static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a) 505{ 506 REQUIRE_64BIT(ctx); 507 REQUIRE_FPU; 508 REQUIRE_ZDINX_OR_D(ctx); 509 REQUIRE_EVEN(ctx, a->rs1); 510 511 TCGv dest = dest_gpr(ctx, a->rd); 512 TCGv_i64 src1 = get_fpr_d(ctx, a->rs1); 513 514 gen_set_rm(ctx, a->rm); 515 gen_helper_fcvt_lu_d(dest, tcg_env, src1); 516 gen_set_gpr(ctx, a->rd, dest); 517 return true; 518} 519 520static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a) 521{ 522 REQUIRE_64BIT(ctx); 523 REQUIRE_FPU; 524 REQUIRE_EXT(ctx, RVD); 525 526#ifdef TARGET_RISCV64 527 gen_set_gpr(ctx, a->rd, cpu_fpr[a->rs1]); 528 return true; 529#else 530 qemu_build_not_reached(); 531#endif 532} 533 534static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a) 535{ 536 REQUIRE_64BIT(ctx); 537 REQUIRE_FPU; 538 REQUIRE_ZDINX_OR_D(ctx); 539 REQUIRE_EVEN(ctx, a->rd); 540 541 TCGv_i64 dest = dest_fpr(ctx, a->rd); 542 TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN); 543 544 gen_set_rm(ctx, a->rm); 545 gen_helper_fcvt_d_l(dest, tcg_env, src); 546 gen_set_fpr_d(ctx, a->rd, dest); 547 548 mark_fs_dirty(ctx); 549 return true; 550} 551 552static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a) 553{ 554 REQUIRE_64BIT(ctx); 555 REQUIRE_FPU; 556 REQUIRE_ZDINX_OR_D(ctx); 557 REQUIRE_EVEN(ctx, a->rd); 558 559 TCGv_i64 dest = dest_fpr(ctx, a->rd); 560 TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO); 561 562 gen_set_rm(ctx, a->rm); 563 gen_helper_fcvt_d_lu(dest, tcg_env, src); 564 gen_set_fpr_d(ctx, a->rd, dest); 565 566 mark_fs_dirty(ctx); 567 return true; 568} 569 570static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a) 571{ 572 REQUIRE_64BIT(ctx); 573 REQUIRE_FPU; 574 REQUIRE_EXT(ctx, RVD); 575 576#ifdef TARGET_RISCV64 577 tcg_gen_mov_tl(cpu_fpr[a->rd], get_gpr(ctx, a->rs1, EXT_NONE)); 578 mark_fs_dirty(ctx); 579 return true; 580#else 581 qemu_build_not_reached(); 582#endif 583} 584