From: Tom Musta Date: Mon, 10 Feb 2014 17:26:59 +0000 (-0600) Subject: target-ppc: Store Quadword X-Git-Tag: v2.0.0-rc0~37^2~42 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=84cab1e2f5be3ea6eaa65c9fc0422fb992946ce0;p=users%2Fdwmw2%2Fqemu.git target-ppc: Store Quadword This patch adds support for the Store Quadword instruction in user mode. Prior to Power ISA 2.07, stq was legal only in privileged mode. Support for Little Endian mode is also new in ISA 2.07. Signed-off-by: Tom Musta Signed-off-by: Alexander Graf --- diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 06372b9d6b..72eff90b31 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -2995,34 +2995,41 @@ static void gen_std(DisasContext *ctx) TCGv EA; rs = rS(ctx->opcode); - if ((ctx->opcode & 0x3) == 0x2) { -#if defined(CONFIG_USER_ONLY) - gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); -#else - /* stq */ - if (unlikely(ctx->mem_idx == 0)) { + if ((ctx->opcode & 0x3) == 0x2) { /* stq */ + + bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; + bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0; + + if (!legal_in_user_mode && is_user_mode(ctx)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } - if (unlikely(rs & 1)) { - gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); + + if (!le_is_supported && ctx->le_mode) { + gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE); return; } - if (unlikely(ctx->le_mode)) { - /* Little-endian mode is not handled */ - gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE); + + if (unlikely(rs & 1)) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); return; } gen_set_access_type(ctx, ACCESS_INT); EA = tcg_temp_new(); gen_addr_imm_index(ctx, EA, 0x03); - gen_qemu_st64(ctx, cpu_gpr[rs], EA); - gen_addr_add(ctx, EA, EA, 8); - gen_qemu_st64(ctx, cpu_gpr[rs+1], EA); + + if (unlikely(ctx->le_mode)) { + gen_qemu_st64(ctx, cpu_gpr[rs+1], EA); + gen_addr_add(ctx, EA, EA, 8); + gen_qemu_st64(ctx, cpu_gpr[rs], EA); + } else { + gen_qemu_st64(ctx, cpu_gpr[rs], EA); + gen_addr_add(ctx, EA, EA, 8); + gen_qemu_st64(ctx, cpu_gpr[rs+1], EA); + } tcg_temp_free(EA); -#endif } else { - /* std / stdu */ + /* std / stdu*/ if (Rc(ctx->opcode)) { if (unlikely(rA(ctx->opcode) == 0)) { gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);