qemu

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

trans_atomic.c.inc (4580B)


      1 /* SPDX-License-Identifier: GPL-2.0-or-later */
      2 /*
      3  * Copyright (c) 2021 Loongson Technology Corporation Limited
      4  */
      5 
      6 static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
      7 {
      8     TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
      9     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     10     TCGv t0 = tcg_temp_new();
     11 
     12     tcg_gen_addi_tl(t0, src1, a->imm);
     13     tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
     14     tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
     15     tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
     16     gen_set_gpr(a->rd, dest, EXT_NONE);
     17     tcg_temp_free(t0);
     18 
     19     return true;
     20 }
     21 
     22 static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
     23 {
     24     TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
     25     TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
     26     TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE);
     27     TCGv t0 = tcg_temp_new();
     28     TCGv val = tcg_temp_new();
     29 
     30     TCGLabel *l1 = gen_new_label();
     31     TCGLabel *done = gen_new_label();
     32 
     33     tcg_gen_addi_tl(t0, src1, a->imm);
     34     tcg_gen_brcond_tl(TCG_COND_EQ, t0, cpu_lladdr, l1);
     35     tcg_gen_movi_tl(dest, 0);
     36     tcg_gen_br(done);
     37 
     38     gen_set_label(l1);
     39     tcg_gen_mov_tl(val, src2);
     40     /* generate cmpxchg */
     41     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval,
     42                               val, ctx->mem_idx, mop);
     43     tcg_gen_setcond_tl(TCG_COND_EQ, dest, t0, cpu_llval);
     44     gen_set_label(done);
     45     gen_set_gpr(a->rd, dest, EXT_NONE);
     46     tcg_temp_free(t0);
     47     tcg_temp_free(val);
     48 
     49     return true;
     50 }
     51 
     52 static bool gen_am(DisasContext *ctx, arg_rrr *a,
     53                    void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
     54                    MemOp mop)
     55 {
     56     TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
     57     TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
     58     TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
     59 
     60     if (a->rd != 0 && (a->rj == a->rd || a->rk == a->rd)) {
     61         qemu_log_mask(LOG_GUEST_ERROR,
     62                       "Warning: source register overlaps destination register"
     63                       "in atomic insn at pc=0x" TARGET_FMT_lx "\n",
     64                       ctx->base.pc_next - 4);
     65         return false;
     66     }
     67 
     68     func(dest, addr, val, ctx->mem_idx, mop);
     69     gen_set_gpr(a->rd, dest, EXT_NONE);
     70 
     71     return true;
     72 }
     73 
     74 TRANS(ll_w, gen_ll, MO_TESL)
     75 TRANS(sc_w, gen_sc, MO_TESL)
     76 TRANS(ll_d, gen_ll, MO_TEUQ)
     77 TRANS(sc_d, gen_sc, MO_TEUQ)
     78 TRANS(amswap_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
     79 TRANS(amswap_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
     80 TRANS(amadd_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
     81 TRANS(amadd_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
     82 TRANS(amand_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
     83 TRANS(amand_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
     84 TRANS(amor_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
     85 TRANS(amor_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
     86 TRANS(amxor_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
     87 TRANS(amxor_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
     88 TRANS(ammax_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
     89 TRANS(ammax_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
     90 TRANS(ammin_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
     91 TRANS(ammin_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
     92 TRANS(ammax_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
     93 TRANS(ammax_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
     94 TRANS(ammin_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
     95 TRANS(ammin_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
     96 TRANS(amswap_db_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
     97 TRANS(amswap_db_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
     98 TRANS(amadd_db_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
     99 TRANS(amadd_db_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
    100 TRANS(amand_db_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
    101 TRANS(amand_db_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
    102 TRANS(amor_db_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
    103 TRANS(amor_db_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
    104 TRANS(amxor_db_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
    105 TRANS(amxor_db_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
    106 TRANS(ammax_db_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
    107 TRANS(ammax_db_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
    108 TRANS(ammin_db_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
    109 TRANS(ammin_db_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
    110 TRANS(ammax_db_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
    111 TRANS(ammax_db_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
    112 TRANS(ammin_db_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
    113 TRANS(ammin_db_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)