target-ppc: Load Quadword

This patch adds the Book I (user space) Load Quadword (lq) instruction.
This instruction was introduced into Book I in Power ISA V2.07.  Previous
versions of the architecture supported this as a privileged instruction.
Previous versions of the architecture also did not support Little Endian
mode.

Note that this patch also adds the PPC_64BX flag to the Power8 model,
which enables the lq instruction.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Tom Musta 2014-02-10 11:26:58 -06:00 committed by Alexander Graf
parent 71a8c019c4
commit e0498daab5
2 changed files with 23 additions and 15 deletions

View File

@ -2872,36 +2872,44 @@ static void gen_ld(DisasContext *ctx)
/* lq */
static void gen_lq(DisasContext *ctx)
{
#if defined(CONFIG_USER_ONLY)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
#else
int ra, rd;
TCGv EA;
/* Restore CPU state */
if (unlikely(ctx->mem_idx == 0)) {
/* lq is a legal user mode instruction starting in ISA 2.07 */
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 (!le_is_supported && ctx->le_mode) {
gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
return;
}
ra = rA(ctx->opcode);
rd = rD(ctx->opcode);
if (unlikely((rd & 1) || rd == ra)) {
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
return;
}
if (unlikely(ctx->le_mode)) {
/* Little-endian mode is not handled */
gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
return;
}
gen_set_access_type(ctx, ACCESS_INT);
EA = tcg_temp_new();
gen_addr_imm_index(ctx, EA, 0x0F);
gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
gen_addr_add(ctx, EA, EA, 8);
gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
if (unlikely(ctx->le_mode)) {
gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
gen_addr_add(ctx, EA, EA, 8);
gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
} else {
gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
gen_addr_add(ctx, EA, EA, 8);
gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
}
tcg_temp_free(EA);
#endif
}
#endif

View File

@ -7165,7 +7165,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
PPC_MEM_SYNC | PPC_MEM_EIEIO |
PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
PPC_64B | PPC_ALTIVEC |
PPC_64B | PPC_64BX | PPC_ALTIVEC |
PPC_SEGMENT_64B | PPC_SLBI |
PPC_POPCNTB | PPC_POPCNTWD;
pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |