On 9/11/19 2:25 AM, liuzhiwei wrote: > + case 64: > + if (vector_elem_mask(env, vm, width, lmul, i)) { > + int64_t tmp; > + idx = (target_long)env->vfp.vreg[src2].s64[j]; > + addr = idx + env->gpr[rs1]; > + > +#ifdef CONFIG_SOFTMMU > + tmp = (int64_t)(int32_t)helper_atomic_xchgl_le(env, addr, > + env->vfp.vreg[src3].s64[j], > + make_memop_idx(memop & ~MO_SIGN, mem_idx)); > +#else > + tmp = (int64_t)(int32_t)helper_atomic_xchgl_le(env, addr, > + env->vfp.vreg[src3].s64[j]); > +#endif > + if (wd) { > + env->vfp.vreg[src3].s64[j] = tmp; > + } > + env->vfp.vstart++; > + } > + break;
This will not link if !defined(CONFIG_ATOMIC64). That's pretty rare these days, admittedly. I think you'd need to compile for ppc32 or mips32 (or riscv32!) host to see this. You can force this condition for i686 host with --extra-cflags='-march=i486', just to see if you've got it right. There should be two different versions of this helper: one that performs actual atomic operations, as above, and a second that performs the same operation with non-atomic operations. The version of the helper that you call should be based on the translation time setting of "tb_cflags(s->base.tb) & CF_PARALLEL": If PARALLEL is set, call the atomic helper otherwise the non-atomic helper. If you arrive at a situation in which the host cannot handle any atomic operation, then you must raise the EXCP_ATOMIC exception. This will halt all other cpus and run one instruction on this cpu while holding the exclusive lock. If you cannot detect this condition any earlier than here at runtime, use cpu_loop_exit_atomic(), but you must do so before altering any cpu state. However, as per my comments for normal loads, you should be able to detect this condition at translation time and call gen_helper_exit_atomic(). r~