On 10.02.2014, at 18:27, Tom Musta <tommu...@gmail.com> wrote: > This patch adds the Store Quadword Conditionl (stqcx.) instruction > which is introduced in Power ISA 2.07. > > Signed-off-by: Tom Musta <tommu...@gmail.com> > --- > V2: Updated linux-user/main.c to use the newly added reserve_val2. > > V3: Fixed erroneousl val2 check per Alex Graf's review. > > linux-user/main.c | 18 +++++++++++++++++- > target-ppc/translate.c | 21 +++++++++++++++++++++ > 2 files changed, 38 insertions(+), 1 deletions(-) > > diff --git a/linux-user/main.c b/linux-user/main.c > index cabc9e1..0cca37d 100644 > --- a/linux-user/main.c > +++ b/linux-user/main.c > @@ -1490,7 +1490,7 @@ static int do_store_exclusive(CPUPPCState *env) > { > target_ulong addr; > target_ulong page_addr; > - target_ulong val; > + target_ulong val, val2; > int flags; > int segv = 0; > > @@ -1513,6 +1513,13 @@ static int do_store_exclusive(CPUPPCState *env) > case 4: segv = get_user_u32(val, addr); break; > #if defined(TARGET_PPC64) > case 8: segv = get_user_u64(val, addr); break; > + case 16: { > + segv = get_user_u64(val, addr); > + if (!segv) { > + segv = get_user_u64(val2, addr + 8); > + } > + break; > + } > #endif > default: abort(); > } > @@ -1524,6 +1531,15 @@ static int do_store_exclusive(CPUPPCState *env) > case 4: segv = put_user_u32(val, addr); break; > #if defined(TARGET_PPC64) > case 8: segv = put_user_u64(val, addr); break; > + case 16: { > + if (val2 == env->reserve_val2) { > + segv = put_user_u64(val, addr); > + if (!segv) { > + segv = put_user_u64(val2, addr + 8); > + } > + } > + break; > + } > #endif > default: abort(); > } > diff --git a/target-ppc/translate.c b/target-ppc/translate.c > index 77de07a..cf0ebc7 100644 > --- a/target-ppc/translate.c > +++ b/target-ppc/translate.c > @@ -3329,6 +3329,20 @@ static void gen_conditional_store(DisasContext *ctx, > TCGv EA, > gen_qemu_st32(ctx, cpu_gpr[reg], EA); > } else if (size == 2) { > gen_qemu_st16(ctx, cpu_gpr[reg], EA); > +#if defined(TARGET_PPC64) > + } else if (size == 16) { > + TCGv gpr1, gpr2; > + if (unlikely(ctx->le_mode)) { > + gpr1 = cpu_gpr[reg+1]; > + gpr2 = cpu_gpr[reg]; > + } else { > + gpr1 = cpu_gpr[reg]; > + gpr2 = cpu_gpr[reg+1]; > + } > + gen_qemu_st64(ctx, gpr1, EA); > + gen_addr_add(ctx, EA, EA, 8);
Please send a follow-up patch on top of this one that creates a temporary in this case for EA+8. It's pretty counterintuitive to have an input variable come out with a different value out of a function. Alex