Revision 968a40f6

b/target-microblaze/helper.h
16 16
DEF_HELPER_2(mmu_write, void, i32, i32)
17 17
#endif
18 18

  
19
DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
20

  
19 21
#include "def-helper.h"
b/target-microblaze/op_helper.c
206 206
    return 0;
207 207
}
208 208

  
209
void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t size)
210
{
211
    uint32_t mask;
212

  
213
    switch (size) {
214
        case 4: mask = 3; break;
215
        case 2: mask = 1; break;
216
        default:
217
        case 1: mask = 0; break;
218
    }
219

  
220
    if (addr & mask) {
221
            qemu_log("unaligned access addr=%x size=%d, wr=%d\n",
222
                     addr, size, wr);
223
            if (!(env->sregs[SR_MSR] & MSR_EE)) {
224
                return;
225
            }
226

  
227
            env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \
228
                                 | (dr & 31) << 5;
229
            if (size == 4) {
230
                env->sregs[SR_ESR] |= 1 << 11;
231
            }
232
            helper_raise_exception(EXCP_HW_EXCP);
233
    }
234
}
235

  
209 236
#if !defined(CONFIG_USER_ONLY)
210 237
/* Writes/reads to the MMU's special regs end up here.  */
211 238
uint32_t helper_mmu_read(uint32_t rn)
b/target-microblaze/translate.c
810 810

  
811 811
    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
812 812
    sync_jmpstate(dc);
813
    if (dc->rd)
813

  
814
    /* Verify alignment if needed.  */
815
    if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
816
        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
817
                            tcg_const_tl(0), tcg_const_tl(size));
818
    }
819

  
820
    if (dc->rd) {
814 821
        gen_load(dc, cpu_R[dc->rd], *addr, size);
815
    else {
822
    } else {
816 823
        gen_load(dc, env_imm, *addr, size);
817 824
    }
818 825

  
......
847 854
    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
848 855
    sync_jmpstate(dc);
849 856
    addr = compute_ldst_addr(dc, &t);
857

  
858
    /* Verify alignment if needed.  */
859
    if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
860
        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
861
                            tcg_const_tl(1), tcg_const_tl(size));
862
    }
863

  
850 864
    gen_store(dc, *addr, cpu_R[dc->rd], size);
851 865
    if (addr == &t)
852 866
        tcg_temp_free(t);

Also available in: Unified diff