qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

trans_rvd.c.inc (14456B)


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