|
@@ -274,8 +274,18 @@ typedef struct DisasContext {
|
|
int mmu_idx;
|
|
int mmu_idx;
|
|
int privilege;
|
|
int privilege;
|
|
bool psw_n_nonzero;
|
|
bool psw_n_nonzero;
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_USER_ONLY
|
|
|
|
+ MemOp unalign;
|
|
|
|
+#endif
|
|
} DisasContext;
|
|
} DisasContext;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_USER_ONLY
|
|
|
|
+#define UNALIGN(C) (C)->unalign
|
|
|
|
+#else
|
|
|
|
+#define UNALIGN(C) 0
|
|
|
|
+#endif
|
|
|
|
+
|
|
/* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */
|
|
/* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */
|
|
static int expand_sm_imm(DisasContext *ctx, int val)
|
|
static int expand_sm_imm(DisasContext *ctx, int val)
|
|
{
|
|
{
|
|
@@ -1475,7 +1485,7 @@ static void do_load_32(DisasContext *ctx, TCGv_i32 dest, unsigned rb,
|
|
|
|
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
- tcg_gen_qemu_ld_reg(dest, addr, ctx->mmu_idx, mop);
|
|
|
|
|
|
+ tcg_gen_qemu_ld_reg(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
|
|
if (modify) {
|
|
if (modify) {
|
|
save_gpr(ctx, rb, ofs);
|
|
save_gpr(ctx, rb, ofs);
|
|
}
|
|
}
|
|
@@ -1493,7 +1503,7 @@ static void do_load_64(DisasContext *ctx, TCGv_i64 dest, unsigned rb,
|
|
|
|
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
- tcg_gen_qemu_ld_i64(dest, addr, ctx->mmu_idx, mop);
|
|
|
|
|
|
+ tcg_gen_qemu_ld_i64(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
|
|
if (modify) {
|
|
if (modify) {
|
|
save_gpr(ctx, rb, ofs);
|
|
save_gpr(ctx, rb, ofs);
|
|
}
|
|
}
|
|
@@ -1511,7 +1521,7 @@ static void do_store_32(DisasContext *ctx, TCGv_i32 src, unsigned rb,
|
|
|
|
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
- tcg_gen_qemu_st_i32(src, addr, ctx->mmu_idx, mop);
|
|
|
|
|
|
+ tcg_gen_qemu_st_i32(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
|
|
if (modify) {
|
|
if (modify) {
|
|
save_gpr(ctx, rb, ofs);
|
|
save_gpr(ctx, rb, ofs);
|
|
}
|
|
}
|
|
@@ -1529,7 +1539,7 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
|
|
|
|
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
ctx->mmu_idx == MMU_PHYS_IDX);
|
|
- tcg_gen_qemu_st_i64(src, addr, ctx->mmu_idx, mop);
|
|
|
|
|
|
+ tcg_gen_qemu_st_i64(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
|
|
if (modify) {
|
|
if (modify) {
|
|
save_gpr(ctx, rb, ofs);
|
|
save_gpr(ctx, rb, ofs);
|
|
}
|
|
}
|
|
@@ -4107,6 +4117,7 @@ static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
|
ctx->mmu_idx = MMU_USER_IDX;
|
|
ctx->mmu_idx = MMU_USER_IDX;
|
|
ctx->iaoq_f = ctx->base.pc_first | MMU_USER_IDX;
|
|
ctx->iaoq_f = ctx->base.pc_first | MMU_USER_IDX;
|
|
ctx->iaoq_b = ctx->base.tb->cs_base | MMU_USER_IDX;
|
|
ctx->iaoq_b = ctx->base.tb->cs_base | MMU_USER_IDX;
|
|
|
|
+ ctx->unalign = (ctx->tb_flags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
|
|
#else
|
|
#else
|
|
ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
|
|
ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
|
|
ctx->mmu_idx = (ctx->tb_flags & PSW_D ? ctx->privilege : MMU_PHYS_IDX);
|
|
ctx->mmu_idx = (ctx->tb_flags & PSW_D ? ctx->privilege : MMU_PHYS_IDX);
|