On 20.02.2014, at 15:20, Alexander Graf <ag...@suse.de> wrote: > > 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.
I've also folded in this patch while applying it to make things compile with --target-list=ppc-linux-user. Alex diff --git a/linux-user/main.c b/linux-user/main.c index 0cca37d..8aa8a3a 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, val2; + target_ulong val, val2 __attribute__((unused)); int flags; int segv = 0;