On 06/20/2018 05:06 AM, Yongbok Kim wrote: > +void helper_llwp(CPUMIPSState *env, target_ulong addr, uint32_t reg1, > + uint32_t reg2, uint32_t mem_idx) > +{ > + if (addr & 0x7) { > + env->CP0_BadVAddr = addr; > + do_raise_exception(env, EXCP_AdEL, GETPC()); > + } > + env->lladdr = do_translate_address(env, addr, 0, GETPC()); > + env->active_tc.gpr[reg1] = env->llval = do_lw(env, addr, mem_idx, > GETPC()); > + env->active_tc.gpr[reg2] = env->llval_wp = do_lw(env, addr + 4, mem_idx, > + GETPC()); > +}
Performing two loads is a mistake. You need to perform one single 64-bit load in order for this to be atomic. There is also no point in performing such out of line. > +target_ulong helper_scwp(CPUMIPSState *env, target_ulong addr, > + uint64_t data, int mem_idx) > +{ > + uint32_t tmp; > + uint32_t tmp2; > + > + if (addr & 0x7) { > + env->CP0_BadVAddr = addr; > + do_raise_exception(env, EXCP_AdES, GETPC()); > + } > + if (do_translate_address(env, addr, 1, GETPC()) == env->lladdr) { > + tmp = do_lw(env, addr, mem_idx, GETPC()); > + tmp2 = do_lw(env, addr + 4, mem_idx, GETPC()); > + if (tmp == env->llval && tmp2 == env->llval_wp) { > + do_sw(env, addr, (uint32_t) data, mem_idx, GETPC()); > + do_sw(env, addr + 4, (uint32_t) *(&data + 4), mem_idx, GETPC()); This must use a 64-bit atomic_cmpxchg. This can also be done inline with tcg_gen_atomic_cmpxchg_i64. r~