@@ -463,6 +463,7 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
#define HW_FLAGS_FP_SP 0x80
#define HW_FLAGS_FP_DP 0x100
#define HW_FLAGS_LSPW 0x200
+#define HW_FLAGS_LAM 0x400
static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
uint64_t *cs_base, uint32_t *flags)
@@ -477,6 +478,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, vaddr *pc,
*flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, FP_SP) * HW_FLAGS_FP_SP;
*flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, FP_DP) * HW_FLAGS_FP_DP;
*flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, LSPW) * HW_FLAGS_LSPW;
+ *flags |= FIELD_EX32(env->cpucfg[2], CPUCFG2, LAM) * HW_FLAGS_LAM;
}
void loongarch_cpu_list(void);
@@ -3,12 +3,20 @@
* Copyright (c) 2021 Loongson Technology Corporation Limited
*/
+#define REQUIRE_LAM do { \
+ if ((ctx->base.tb->flags & HW_FLAGS_LAM) == 0) { \
+ return false; \
+ } \
+} while (0)
+
static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
{
TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
TCGv t0 = make_address_i(ctx, src1, a->imm);
+ REQUIRE_LAM;
+
tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
@@ -25,6 +33,8 @@ static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
TCGv t0 = tcg_temp_new();
TCGv val = tcg_temp_new();
+ REQUIRE_LAM;
+
TCGLabel *l1 = gen_new_label();
TCGLabel *done = gen_new_label();
@@ -53,6 +63,8 @@ static bool gen_am(DisasContext *ctx, arg_rrr *a,
TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
+ REQUIRE_LAM;
+
if (a->rd != 0 && (a->rj == a->rd || a->rk == a->rd)) {
qemu_log_mask(LOG_GUEST_ERROR,
"Warning: source register overlaps destination register"
Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.h | 2 ++ target/loongarch/insn_trans/trans_atomic.c.inc | 12 ++++++++++++ 2 files changed, 14 insertions(+)