From: Tom Musta Date: Mon, 10 Feb 2014 17:26:59 +0000 (-0600) Subject: target-ppc: Store Quadword X-Git-Url: https://repo.jachan.dev/qemu.git/commitdiff_plain/84cab1e2f5be3ea6eaa65c9fc0422fb992946ce0 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);