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? (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. (3) Use cpu_ldq_data_ra within the helper to perform the memory loads. r~