From 84cab1e2f5be3ea6eaa65c9fc0422fb992946ce0 Mon Sep 17 00:00:00 2001 From: Tom Musta Date: Mon, 10 Feb 2014 11:26:59 -0600 Subject: 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 --- target-ppc/translate.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'target-ppc') 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); -- cgit v1.2.1