cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

trans_rvd.c.inc (10593B)


      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
     21static bool trans_fld(DisasContext *ctx, arg_fld *a)
     22{
     23    TCGv addr;
     24
     25    REQUIRE_FPU;
     26    REQUIRE_EXT(ctx, RVD);
     27
     28    addr = get_gpr(ctx, a->rs1, EXT_NONE);
     29    if (a->imm) {
     30        TCGv temp = temp_new(ctx);
     31        tcg_gen_addi_tl(temp, addr, a->imm);
     32        addr = temp;
     33    }
     34
     35    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
     36
     37    mark_fs_dirty(ctx);
     38    return true;
     39}
     40
     41static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
     42{
     43    TCGv addr;
     44
     45    REQUIRE_FPU;
     46    REQUIRE_EXT(ctx, RVD);
     47
     48    addr = get_gpr(ctx, a->rs1, EXT_NONE);
     49    if (a->imm) {
     50        TCGv temp = temp_new(ctx);
     51        tcg_gen_addi_tl(temp, addr, a->imm);
     52        addr = temp;
     53    }
     54
     55    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
     56
     57    return true;
     58}
     59
     60static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
     61{
     62    REQUIRE_FPU;
     63    REQUIRE_EXT(ctx, RVD);
     64    gen_set_rm(ctx, a->rm);
     65    gen_helper_fmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
     66                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
     67    mark_fs_dirty(ctx);
     68    return true;
     69}
     70
     71static bool trans_fmsub_d(DisasContext *ctx, arg_fmsub_d *a)
     72{
     73    REQUIRE_FPU;
     74    REQUIRE_EXT(ctx, RVD);
     75    gen_set_rm(ctx, a->rm);
     76    gen_helper_fmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
     77                       cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
     78    mark_fs_dirty(ctx);
     79    return true;
     80}
     81
     82static bool trans_fnmsub_d(DisasContext *ctx, arg_fnmsub_d *a)
     83{
     84    REQUIRE_FPU;
     85    REQUIRE_EXT(ctx, RVD);
     86    gen_set_rm(ctx, a->rm);
     87    gen_helper_fnmsub_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
     88                        cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
     89    mark_fs_dirty(ctx);
     90    return true;
     91}
     92
     93static bool trans_fnmadd_d(DisasContext *ctx, arg_fnmadd_d *a)
     94{
     95    REQUIRE_FPU;
     96    REQUIRE_EXT(ctx, RVD);
     97    gen_set_rm(ctx, a->rm);
     98    gen_helper_fnmadd_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1],
     99                        cpu_fpr[a->rs2], cpu_fpr[a->rs3]);
    100    mark_fs_dirty(ctx);
    101    return true;
    102}
    103
    104static bool trans_fadd_d(DisasContext *ctx, arg_fadd_d *a)
    105{
    106    REQUIRE_FPU;
    107    REQUIRE_EXT(ctx, RVD);
    108
    109    gen_set_rm(ctx, a->rm);
    110    gen_helper_fadd_d(cpu_fpr[a->rd], cpu_env,
    111                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    112
    113    mark_fs_dirty(ctx);
    114    return true;
    115}
    116
    117static bool trans_fsub_d(DisasContext *ctx, arg_fsub_d *a)
    118{
    119    REQUIRE_FPU;
    120    REQUIRE_EXT(ctx, RVD);
    121
    122    gen_set_rm(ctx, a->rm);
    123    gen_helper_fsub_d(cpu_fpr[a->rd], cpu_env,
    124                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    125
    126    mark_fs_dirty(ctx);
    127    return true;
    128}
    129
    130static bool trans_fmul_d(DisasContext *ctx, arg_fmul_d *a)
    131{
    132    REQUIRE_FPU;
    133    REQUIRE_EXT(ctx, RVD);
    134
    135    gen_set_rm(ctx, a->rm);
    136    gen_helper_fmul_d(cpu_fpr[a->rd], cpu_env,
    137                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    138
    139    mark_fs_dirty(ctx);
    140    return true;
    141}
    142
    143static bool trans_fdiv_d(DisasContext *ctx, arg_fdiv_d *a)
    144{
    145    REQUIRE_FPU;
    146    REQUIRE_EXT(ctx, RVD);
    147
    148    gen_set_rm(ctx, a->rm);
    149    gen_helper_fdiv_d(cpu_fpr[a->rd], cpu_env,
    150                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    151
    152    mark_fs_dirty(ctx);
    153    return true;
    154}
    155
    156static bool trans_fsqrt_d(DisasContext *ctx, arg_fsqrt_d *a)
    157{
    158    REQUIRE_FPU;
    159    REQUIRE_EXT(ctx, RVD);
    160
    161    gen_set_rm(ctx, a->rm);
    162    gen_helper_fsqrt_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
    163
    164    mark_fs_dirty(ctx);
    165    return true;
    166}
    167
    168static bool trans_fsgnj_d(DisasContext *ctx, arg_fsgnj_d *a)
    169{
    170    if (a->rs1 == a->rs2) { /* FMOV */
    171        tcg_gen_mov_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1]);
    172    } else {
    173        tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rs2],
    174                            cpu_fpr[a->rs1], 0, 63);
    175    }
    176    mark_fs_dirty(ctx);
    177    return true;
    178}
    179
    180static bool trans_fsgnjn_d(DisasContext *ctx, arg_fsgnjn_d *a)
    181{
    182    REQUIRE_FPU;
    183    REQUIRE_EXT(ctx, RVD);
    184    if (a->rs1 == a->rs2) { /* FNEG */
    185        tcg_gen_xori_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], INT64_MIN);
    186    } else {
    187        TCGv_i64 t0 = tcg_temp_new_i64();
    188        tcg_gen_not_i64(t0, cpu_fpr[a->rs2]);
    189        tcg_gen_deposit_i64(cpu_fpr[a->rd], t0, cpu_fpr[a->rs1], 0, 63);
    190        tcg_temp_free_i64(t0);
    191    }
    192    mark_fs_dirty(ctx);
    193    return true;
    194}
    195
    196static bool trans_fsgnjx_d(DisasContext *ctx, arg_fsgnjx_d *a)
    197{
    198    REQUIRE_FPU;
    199    REQUIRE_EXT(ctx, RVD);
    200    if (a->rs1 == a->rs2) { /* FABS */
    201        tcg_gen_andi_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], ~INT64_MIN);
    202    } else {
    203        TCGv_i64 t0 = tcg_temp_new_i64();
    204        tcg_gen_andi_i64(t0, cpu_fpr[a->rs2], INT64_MIN);
    205        tcg_gen_xor_i64(cpu_fpr[a->rd], cpu_fpr[a->rs1], t0);
    206        tcg_temp_free_i64(t0);
    207    }
    208    mark_fs_dirty(ctx);
    209    return true;
    210}
    211
    212static bool trans_fmin_d(DisasContext *ctx, arg_fmin_d *a)
    213{
    214    REQUIRE_FPU;
    215    REQUIRE_EXT(ctx, RVD);
    216
    217    gen_helper_fmin_d(cpu_fpr[a->rd], cpu_env,
    218                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    219
    220    mark_fs_dirty(ctx);
    221    return true;
    222}
    223
    224static bool trans_fmax_d(DisasContext *ctx, arg_fmax_d *a)
    225{
    226    REQUIRE_FPU;
    227    REQUIRE_EXT(ctx, RVD);
    228
    229    gen_helper_fmax_d(cpu_fpr[a->rd], cpu_env,
    230                      cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    231
    232    mark_fs_dirty(ctx);
    233    return true;
    234}
    235
    236static bool trans_fcvt_s_d(DisasContext *ctx, arg_fcvt_s_d *a)
    237{
    238    REQUIRE_FPU;
    239    REQUIRE_EXT(ctx, RVD);
    240
    241    gen_set_rm(ctx, a->rm);
    242    gen_helper_fcvt_s_d(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
    243
    244    mark_fs_dirty(ctx);
    245    return true;
    246}
    247
    248static bool trans_fcvt_d_s(DisasContext *ctx, arg_fcvt_d_s *a)
    249{
    250    REQUIRE_FPU;
    251    REQUIRE_EXT(ctx, RVD);
    252
    253    gen_set_rm(ctx, a->rm);
    254    gen_helper_fcvt_d_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
    255
    256    mark_fs_dirty(ctx);
    257    return true;
    258}
    259
    260static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
    261{
    262    REQUIRE_FPU;
    263    REQUIRE_EXT(ctx, RVD);
    264
    265    TCGv dest = dest_gpr(ctx, a->rd);
    266
    267    gen_helper_feq_d(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    268    gen_set_gpr(ctx, a->rd, dest);
    269    return true;
    270}
    271
    272static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
    273{
    274    REQUIRE_FPU;
    275    REQUIRE_EXT(ctx, RVD);
    276
    277    TCGv dest = dest_gpr(ctx, a->rd);
    278
    279    gen_helper_flt_d(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    280    gen_set_gpr(ctx, a->rd, dest);
    281    return true;
    282}
    283
    284static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
    285{
    286    REQUIRE_FPU;
    287    REQUIRE_EXT(ctx, RVD);
    288
    289    TCGv dest = dest_gpr(ctx, a->rd);
    290
    291    gen_helper_fle_d(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
    292    gen_set_gpr(ctx, a->rd, dest);
    293    return true;
    294}
    295
    296static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
    297{
    298    REQUIRE_FPU;
    299    REQUIRE_EXT(ctx, RVD);
    300
    301    TCGv dest = dest_gpr(ctx, a->rd);
    302
    303    gen_helper_fclass_d(dest, cpu_fpr[a->rs1]);
    304    gen_set_gpr(ctx, a->rd, dest);
    305    return true;
    306}
    307
    308static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
    309{
    310    REQUIRE_FPU;
    311    REQUIRE_EXT(ctx, RVD);
    312
    313    TCGv dest = dest_gpr(ctx, a->rd);
    314
    315    gen_set_rm(ctx, a->rm);
    316    gen_helper_fcvt_w_d(dest, cpu_env, cpu_fpr[a->rs1]);
    317    gen_set_gpr(ctx, a->rd, dest);
    318    return true;
    319}
    320
    321static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
    322{
    323    REQUIRE_FPU;
    324    REQUIRE_EXT(ctx, RVD);
    325
    326    TCGv dest = dest_gpr(ctx, a->rd);
    327
    328    gen_set_rm(ctx, a->rm);
    329    gen_helper_fcvt_wu_d(dest, cpu_env, cpu_fpr[a->rs1]);
    330    gen_set_gpr(ctx, a->rd, dest);
    331    return true;
    332}
    333
    334static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
    335{
    336    REQUIRE_FPU;
    337    REQUIRE_EXT(ctx, RVD);
    338
    339    TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN);
    340
    341    gen_set_rm(ctx, a->rm);
    342    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, src);
    343
    344    mark_fs_dirty(ctx);
    345    return true;
    346}
    347
    348static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
    349{
    350    REQUIRE_FPU;
    351    REQUIRE_EXT(ctx, RVD);
    352
    353    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
    354
    355    gen_set_rm(ctx, a->rm);
    356    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, src);
    357
    358    mark_fs_dirty(ctx);
    359    return true;
    360}
    361
    362static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
    363{
    364    REQUIRE_64BIT(ctx);
    365    REQUIRE_FPU;
    366    REQUIRE_EXT(ctx, RVD);
    367
    368    TCGv dest = dest_gpr(ctx, a->rd);
    369
    370    gen_set_rm(ctx, a->rm);
    371    gen_helper_fcvt_l_d(dest, cpu_env, cpu_fpr[a->rs1]);
    372    gen_set_gpr(ctx, a->rd, dest);
    373    return true;
    374}
    375
    376static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
    377{
    378    REQUIRE_64BIT(ctx);
    379    REQUIRE_FPU;
    380    REQUIRE_EXT(ctx, RVD);
    381
    382    TCGv dest = dest_gpr(ctx, a->rd);
    383
    384    gen_set_rm(ctx, a->rm);
    385    gen_helper_fcvt_lu_d(dest, cpu_env, cpu_fpr[a->rs1]);
    386    gen_set_gpr(ctx, a->rd, dest);
    387    return true;
    388}
    389
    390static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
    391{
    392    REQUIRE_64BIT(ctx);
    393    REQUIRE_FPU;
    394    REQUIRE_EXT(ctx, RVD);
    395
    396#ifdef TARGET_RISCV64
    397    gen_set_gpr(ctx, a->rd, cpu_fpr[a->rs1]);
    398    return true;
    399#else
    400    qemu_build_not_reached();
    401#endif
    402}
    403
    404static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
    405{
    406    REQUIRE_64BIT(ctx);
    407    REQUIRE_FPU;
    408    REQUIRE_EXT(ctx, RVD);
    409
    410    TCGv src = get_gpr(ctx, a->rs1, EXT_SIGN);
    411
    412    gen_set_rm(ctx, a->rm);
    413    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, src);
    414
    415    mark_fs_dirty(ctx);
    416    return true;
    417}
    418
    419static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
    420{
    421    REQUIRE_64BIT(ctx);
    422    REQUIRE_FPU;
    423    REQUIRE_EXT(ctx, RVD);
    424
    425    TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO);
    426
    427    gen_set_rm(ctx, a->rm);
    428    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, src);
    429
    430    mark_fs_dirty(ctx);
    431    return true;
    432}
    433
    434static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
    435{
    436    REQUIRE_64BIT(ctx);
    437    REQUIRE_FPU;
    438    REQUIRE_EXT(ctx, RVD);
    439
    440#ifdef TARGET_RISCV64
    441    tcg_gen_mov_tl(cpu_fpr[a->rd], get_gpr(ctx, a->rs1, EXT_NONE));
    442    mark_fs_dirty(ctx);
    443    return true;
    444#else
    445    qemu_build_not_reached();
    446#endif
    447}