On 09/27/2014 07:58 AM, Bastian Koppelmann wrote:
> +/* ld circ */
> +DEF_HELPER_4(ld_b_circ, void, env, i32, i32, int)

Avoid, whenever possible, performing memory operations within helpers.  Doing
that complicates the generation of correct code for exact exceptions from the
memory operation.  I'm not saying it can't be done, but what you're doing right
now certainly isn't correct, and it's easier to do the memory operation with
tcg ops.

So now we need to find an efficient way to do this.  In both cases, I think one
helper each for bit-reverse and circular modes should suffice.

E.g.

        tcg_gen_ext16u_tl(temp, A[b+1])
        tcg_gen_add_tl(ea, A[b], temp)
        tcg_gen_qemu_ld_tl(ret, ea, mmu_idx, MO_UB)
        gen_helper_br_update(A[b+1], A[b+1])

and then

uint32_t helper_br_update(uint32_t reg)
{
    uint32_t index = reg & 0xffff;
    uint32_t incr = reg >> 16;
    uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
    return reg - index + new_index;
}

uint32_t helper_circ_update(uint32_t reg, uint32_t off)
{
    uint32_t index = reg & 0xffff;
    uint32_t length = reg >> 16;
    int32_t new_index = index + off;
    if (new_index < 0) {
        new_index += length;
    } else {
        new_index %= length;
    }
    return reg - index + new_index;
}


> +void helper_ld_w_circ(CPUTriCoreState *env, uint32_t r1, uint32_t r2, int 
> off10)
> +{
> +    CIRC_BR_DEFINES(r2)
> +
> +    uint32_t ea0 = env->gpr_a[r2] + index;
> +    uint32_t ea2 = env->gpr_a[r2] + (index + 2 % length_incr);
> +
> +    uint32_t hw_ea2 = cpu_lduw_data(env, ea2) << 16;
> +    uint32_t lw_ea0 = cpu_lduw_data(env, ea0);
> +
> +    env->gpr_d[r1] = hw_ea2 | lw_ea0;
> +
> +    CIRC_CALC_INDEX(r2, off10, length_incr);
> +}

I know that the volume 2 pseudo code for LD.W says two halfword loads, but the
volume 1 text, section 2.5.5 says that the buffer end must be aligned to the
size of the access.  As I read it, two memory operations should not be required.


r~

Reply via email to