From 21ee07e7737a2dbba226a8d8192246e51855910d Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 5 Jun 2023 12:54:45 +1000 Subject: [PATCH] target/ppc: Rework store conditional to avoid branch Rework store conditional to avoid a branch in the success case. Change some of the variable names and layout while here so gen_conditional_store more closely matches gen_stqcx_. Reviewed-by: Richard Henderson Signed-off-by: Nicholas Piggin Message-Id: <20230605025445.161932-4-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 67 ++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index cb4764476d..b591f2e496 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -3697,31 +3697,32 @@ static void gen_stdat(DisasContext *ctx) static void gen_conditional_store(DisasContext *ctx, MemOp memop) { - TCGLabel *l1 = gen_new_label(); - TCGLabel *l2 = gen_new_label(); - TCGv t0 = tcg_temp_new(); - int reg = rS(ctx->opcode); - - gen_set_access_type(ctx, ACCESS_RES); - gen_addr_reg_index(ctx, t0); - tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(memop), l1); + TCGLabel *lfail; + TCGv EA; + TCGv cr0; + TCGv t0; + int rs = rS(ctx->opcode); + lfail = gen_new_label(); + EA = tcg_temp_new(); + cr0 = tcg_temp_new(); t0 = tcg_temp_new(); + + tcg_gen_mov_tl(cr0, cpu_so); + gen_set_access_type(ctx, ACCESS_RES); + gen_addr_reg_index(ctx, EA); + tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(memop), lfail); + tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val, - cpu_gpr[reg], ctx->mem_idx, + cpu_gpr[rs], ctx->mem_idx, DEF_MEMOP(memop) | MO_ALIGN); tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val); tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT); - tcg_gen_or_tl(t0, t0, cpu_so); - tcg_gen_trunc_tl_i32(cpu_crf[0], t0); - tcg_gen_br(l2); + tcg_gen_or_tl(cr0, cr0, t0); - gen_set_label(l1); - - tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); - - gen_set_label(l2); + gen_set_label(lfail); + tcg_gen_trunc_tl_i32(cpu_crf[0], cr0); tcg_gen_movi_tl(cpu_reserve, -1); } @@ -3775,25 +3776,26 @@ static void gen_lqarx(DisasContext *ctx) /* stqcx. */ static void gen_stqcx_(DisasContext *ctx) { - TCGLabel *lab_fail, *lab_over; - int rs = rS(ctx->opcode); + TCGLabel *lfail; TCGv EA, t0, t1; + TCGv cr0; TCGv_i128 cmp, val; + int rs = rS(ctx->opcode); if (unlikely(rs & 1)) { gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); return; } - lab_fail = gen_new_label(); - lab_over = gen_new_label(); - - gen_set_access_type(ctx, ACCESS_RES); + lfail = gen_new_label(); EA = tcg_temp_new(); - gen_addr_reg_index(ctx, EA); + cr0 = tcg_temp_new(); - tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lab_fail); - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lab_fail); + tcg_gen_mov_tl(cr0, cpu_so); + gen_set_access_type(ctx, ACCESS_RES); + gen_addr_reg_index(ctx, EA); + tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail); + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lfail); cmp = tcg_temp_new_i128(); val = tcg_temp_new_i128(); @@ -3816,15 +3818,10 @@ static void gen_stqcx_(DisasContext *ctx) tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, 0); tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT); - tcg_gen_or_tl(t0, t0, cpu_so); - tcg_gen_trunc_tl_i32(cpu_crf[0], t0); + tcg_gen_or_tl(cr0, cr0, t0); - tcg_gen_br(lab_over); - gen_set_label(lab_fail); - - tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); - - gen_set_label(lab_over); + gen_set_label(lfail); + tcg_gen_trunc_tl_i32(cpu_crf[0], cr0); tcg_gen_movi_tl(cpu_reserve, -1); } #endif /* defined(TARGET_PPC64) */