On Tue, Jan 21, 2014 at 08:12:12PM +0000, Peter Maydell wrote: > System mode store-exclusive use a different code path to usermode ones; > implement this missing code, in a similar way to the 32 bit version. > > Signed-off-by: Peter Maydell <peter.maydell@xxxxxxxxxx> > --- > target-arm/translate-a64.c | 68 ++++++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 62 insertions(+), 6 deletions(-) > > diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c > index e0f6765..5aa1f17 100644 > --- a/target-arm/translate-a64.c > +++ b/target-arm/translate-a64.c > @@ -1422,12 +1422,68 @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, > } > #else > static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2, > - TCGv_i64 addr, int size, int is_pair) > -{ > - qemu_log_mask(LOG_UNIMP, > - "%s:%d: system mode store_exclusive unsupported " > - "at pc=%016" PRIx64 "\n", > - __FILE__, __LINE__, s->pc - 4); > + TCGv_i64 inaddr, int size, int is_pair) > +{ > + /* if (env->exclusive_addr == addr && env->exclusive_val == [addr] > + * && (!is_pair || env->exclusive_high == [addr + datasize])) { > + * [addr] = {Rt}; > + * if (is_pair) { > + * [addr + datasize] = {Rt2}; > + * } > + * {Rd} = 0; > + * } else { > + * {Rd} = 1; > + * } > + * env->exclusive_addr = -1; > + */ > + int fail_label = gen_new_label(); > + int done_label = gen_new_label(); > + TCGv_i64 addr = tcg_temp_local_new_i64(); > + TCGv_i64 tmp; > + > + /* Copy input into a local temp so it is not trashed when the > + * basic block ends at the branch insn. > + */ > + tcg_gen_mov_i64(addr, inaddr); > + tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label); > + > + tmp = tcg_temp_new_i64(); > + tcg_gen_qemu_ld_i64(tmp, addr, get_mem_index(s), MO_TE + size); > + tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label); > + tcg_temp_free_i64(tmp); > + > + if (is_pair) { > + TCGv_i64 addrhi = tcg_temp_new_i64(); > + TCGv_i64 tmphi = tcg_temp_new_i64(); > + > + tcg_gen_addi_i64(addrhi, addr, 1 << size); > + tcg_gen_qemu_ld_i64(tmphi, addrhi, get_mem_index(s), MO_TE + size); > + tcg_gen_brcond_i64(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label); s/tmp/tmphi/ > + > + tcg_temp_free_i64(tmphi); > + tcg_temp_free_i64(addrhi); Can addrhi be saved and free after doing store? > + } > + > + /* We seem to still have the exclusive monitor, so do the store */ > + tcg_gen_qemu_st_i64(cpu_reg(s, rt), addr, get_mem_index(s), MO_TE + size); > + if (is_pair) { > + TCGv_i64 addrhi = tcg_temp_new_i64(); > + > + tcg_gen_addi_i64(addrhi, addr, 1 << size); > + tcg_gen_qemu_st_i64(cpu_reg(s, rt2), addrhi, > + get_mem_index(s), MO_TE + size); > + tcg_temp_free_i64(addrhi); > + } > + > + tcg_temp_free_i64(addr); > + > + tcg_gen_movi_i64(cpu_reg(s, rd), 0); > + tcg_gen_br(done_label); > + gen_set_label(fail_label); > + tcg_gen_movi_i64(cpu_reg(s, rd), 1); > + gen_set_label(done_label); > + tcg_gen_movi_i64(cpu_exclusive_addr, -1); > + > } > #endif > > -- > 1.8.5 > > _______________________________________________ > kvmarm mailing list > kvmarm@xxxxxxxxxxxxxxxxxxxxx > https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm