Richard Henderson <r...@twiddle.net> writes: > On 11/29/2016 11:56 PM, Nikunj A Dadhania wrote: >> Lets bring full example here. >> >> TCGv nb = tcg_temp_new(); >> tcg_gen_andi_tl(nb, cpu_gpr[rB(ctx->opcode)], 0xFF); >> tcg_gen_brcondi_tl(TCG_COND_EQ, nb, 0, l1); >> >> /* do something */ >> gen_set_access_type(ctx, ACCESS_INT); >> EA = tcg_temp_new(); >> gen_addr_register(ctx, EA); >> tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_LEQ); >> tcg_gen_addi_tl(EA, EA, 8); >> tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_LEQ); >> opc = tcg_const_i32(ctx->opcode); >> gen_helper_lxvl(cpu_env, opc, nb); /* <--- That uses nb */ >> tcg_temp_free_i32(opc); >> tcg_temp_free(EA); >> >> gen_set_label(l1); >> tcg_temp_free(nb); >> >>> The plain temporary is only valid to the end of a basic >>> block, and brcond ends a basic block. So you can free >>> the temp after the brcond but you can't do anything >>> else with it. >> >> In the above case, assuming that nb is a plain temporary, case nb != 0 >> worked fine (by fluke?), i.e. no branch. >> >> While when nb == 0, failed, i.e. branch taken to l1, and just free nb. I >> am not using "nb" in this case. > > This is also a good example of why you should preferentially avoid branches > within the tcg opcode stream. > > In the case of lxvl, I strongly suggest that you push *everything* into the > helper. In particular: > > (1) Passing the full instruction opcode means you've got to re-parse. > Why are you not passing a pointer to the XT register like other > VSX helpers?
Sure, I can do that. No particular reason though. > (2) As I read it, this is wrong, since when NB == 0, XT is assigned 0. > Which you are not doing, having skipped over the helper. I am doing that in my code. Didn't want to complicate the example code above. > (3) Use cpu_ldq_data_ra within the helper to perform the memory > loads. Let me try that. Regards Nikunj