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~