target-ppc: move out stqcx impementation
Being a 16byte operation, qemu_ld/st still does not support this. Move this out so other store operation can use qemu_ld/st in the following patch. Also, convert it to two MO_Q operations for stqcx. Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
48793c95c9
commit
aa2008af0c
@ -3105,22 +3105,6 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
|
|||||||
gen_qemu_st32(ctx, cpu_gpr[reg], EA);
|
gen_qemu_st32(ctx, cpu_gpr[reg], EA);
|
||||||
} else if (size == 2) {
|
} else if (size == 2) {
|
||||||
gen_qemu_st16(ctx, cpu_gpr[reg], EA);
|
gen_qemu_st16(ctx, cpu_gpr[reg], EA);
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
} else if (size == 16) {
|
|
||||||
TCGv gpr1, gpr2 , EA8;
|
|
||||||
if (unlikely(ctx->le_mode)) {
|
|
||||||
gpr1 = cpu_gpr[reg+1];
|
|
||||||
gpr2 = cpu_gpr[reg];
|
|
||||||
} else {
|
|
||||||
gpr1 = cpu_gpr[reg];
|
|
||||||
gpr2 = cpu_gpr[reg+1];
|
|
||||||
}
|
|
||||||
gen_qemu_st64_i64(ctx, gpr1, EA);
|
|
||||||
EA8 = tcg_temp_local_new();
|
|
||||||
gen_addr_add(ctx, EA8, EA, 8);
|
|
||||||
gen_qemu_st64_i64(ctx, gpr2, EA8);
|
|
||||||
tcg_temp_free(EA8);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
gen_qemu_st8(ctx, cpu_gpr[reg], EA);
|
gen_qemu_st8(ctx, cpu_gpr[reg], EA);
|
||||||
}
|
}
|
||||||
@ -3133,11 +3117,6 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
|
|||||||
static void gen_##name(DisasContext *ctx) \
|
static void gen_##name(DisasContext *ctx) \
|
||||||
{ \
|
{ \
|
||||||
TCGv t0; \
|
TCGv t0; \
|
||||||
if (unlikely((len == 16) && (rD(ctx->opcode) & 1))) { \
|
|
||||||
gen_inval_exception(ctx, \
|
|
||||||
POWERPC_EXCP_INVAL_INVAL); \
|
|
||||||
return; \
|
|
||||||
} \
|
|
||||||
gen_set_access_type(ctx, ACCESS_RES); \
|
gen_set_access_type(ctx, ACCESS_RES); \
|
||||||
t0 = tcg_temp_local_new(); \
|
t0 = tcg_temp_local_new(); \
|
||||||
gen_addr_reg_index(ctx, t0); \
|
gen_addr_reg_index(ctx, t0); \
|
||||||
@ -3190,9 +3169,55 @@ static void gen_lqarx(DisasContext *ctx)
|
|||||||
tcg_temp_free(EA);
|
tcg_temp_free(EA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* stqcx. */
|
||||||
|
static void gen_stqcx_(DisasContext *ctx)
|
||||||
|
{
|
||||||
|
TCGv EA;
|
||||||
|
int reg = rS(ctx->opcode);
|
||||||
|
int len = 16;
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
TCGLabel *l1;
|
||||||
|
TCGv gpr1, gpr2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (unlikely((rD(ctx->opcode) & 1))) {
|
||||||
|
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gen_set_access_type(ctx, ACCESS_RES);
|
||||||
|
EA = tcg_temp_local_new();
|
||||||
|
gen_addr_reg_index(ctx, EA);
|
||||||
|
if (len > 1) {
|
||||||
|
gen_check_align(ctx, EA, (len) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_USER_ONLY)
|
||||||
|
gen_conditional_store(ctx, EA, reg, 16);
|
||||||
|
#else
|
||||||
|
tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
|
||||||
|
l1 = gen_new_label();
|
||||||
|
tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
|
||||||
|
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
|
||||||
|
|
||||||
|
if (unlikely(ctx->le_mode)) {
|
||||||
|
gpr1 = cpu_gpr[reg + 1];
|
||||||
|
gpr2 = cpu_gpr[reg];
|
||||||
|
} else {
|
||||||
|
gpr1 = cpu_gpr[reg];
|
||||||
|
gpr2 = cpu_gpr[reg + 1];
|
||||||
|
}
|
||||||
|
tcg_gen_qemu_st_tl(gpr1, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
|
||||||
|
gen_addr_add(ctx, EA, EA, 8);
|
||||||
|
tcg_gen_qemu_st_tl(gpr2, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
|
||||||
|
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_movi_tl(cpu_reserve, -1);
|
||||||
|
#endif
|
||||||
|
tcg_temp_free(EA);
|
||||||
|
}
|
||||||
|
|
||||||
/* stdcx. */
|
/* stdcx. */
|
||||||
STCX(stdcx_, 8);
|
STCX(stdcx_, 8);
|
||||||
STCX(stqcx_, 16);
|
|
||||||
#endif /* defined(TARGET_PPC64) */
|
#endif /* defined(TARGET_PPC64) */
|
||||||
|
|
||||||
/* sync */
|
/* sync */
|
||||||
|
Loading…
Reference in New Issue
Block a user