target/ppc: Move LQ and STQ to decodetree

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
Message-Id: <20211029202424.175401-6-matheus.ferst@eldorado.org.br>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Matheus Ferst 2021-10-29 17:23:55 -03:00 committed by David Gibson
parent dcb4e5b72c
commit e10271e104
3 changed files with 113 additions and 151 deletions

View File

@ -24,9 +24,16 @@
@D_bfs ...... bf:3 - l:1 ra:5 imm:s16 &D_bf @D_bfs ...... bf:3 - l:1 ra:5 imm:s16 &D_bf
@D_bfu ...... bf:3 - l:1 ra:5 imm:16 &D_bf @D_bfu ...... bf:3 - l:1 ra:5 imm:16 &D_bf
%dq_si 4:s12 !function=times_16
%dq_rtp 22:4 !function=times_2
@DQ_rtp ...... ....0 ra:5 ............ .... &D rt=%dq_rtp si=%dq_si
%ds_si 2:s14 !function=times_4 %ds_si 2:s14 !function=times_4
@DS ...... rt:5 ra:5 .............. .. &D si=%ds_si @DS ...... rt:5 ra:5 .............. .. &D si=%ds_si
%ds_rtp 22:4 !function=times_2
@DS_rtp ...... ....0 ra:5 .............. .. &D rt=%ds_rtp si=%ds_si
&DX rt d &DX rt d
%dx_d 6:s10 16:5 0:1 %dx_d 6:s10 16:5 0:1
@DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d @DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d
@ -74,6 +81,8 @@ LDU 111010 ..... ..... ..............01 @DS
LDX 011111 ..... ..... ..... 0000010101 - @X LDX 011111 ..... ..... ..... 0000010101 - @X
LDUX 011111 ..... ..... ..... 0000110101 - @X LDUX 011111 ..... ..... ..... 0000110101 - @X
LQ 111000 ..... ..... ............ ---- @DQ_rtp
### Fixed-Point Store Instructions ### Fixed-Point Store Instructions
STB 100110 ..... ..... ................ @D STB 100110 ..... ..... ................ @D
@ -96,6 +105,8 @@ STDU 111110 ..... ..... ..............01 @DS
STDX 011111 ..... ..... ..... 0010010101 - @X STDX 011111 ..... ..... ..... 0010010101 - @X
STDUX 011111 ..... ..... ..... 0010110101 - @X STDUX 011111 ..... ..... ..... 0010110101 - @X
STQ 111110 ..... ..... ..............10 @DS_rtp
### Fixed-Point Compare Instructions ### Fixed-Point Compare Instructions
CMP 011111 ... - . ..... ..... 0000000000 - @X_bfl CMP 011111 ... - . ..... ..... 0000000000 - @X_bfl

View File

@ -3327,69 +3327,6 @@ GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST) GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST) GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
/* lq */
static void gen_lq(DisasContext *ctx)
{
int ra, rd;
TCGv EA, hi, lo;
/* 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 && ctx->pr) {
gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
if (!le_is_supported && ctx->le_mode) {
gen_align_no_le(ctx);
return;
}
ra = rA(ctx->opcode);
rd = rD(ctx->opcode);
if (unlikely((rd & 1) || rd == ra)) {
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, 0x0F);
/* Note that the low part is always in RD+1, even in LE mode. */
lo = cpu_gpr[rd + 1];
hi = cpu_gpr[rd];
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
if (HAVE_ATOMIC128) {
TCGv_i32 oi = tcg_temp_new_i32();
if (ctx->le_mode) {
tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
} else {
tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
}
tcg_temp_free_i32(oi);
tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
} else {
/* Restart with exclusive lock. */
gen_helper_exit_atomic(cpu_env);
ctx->base.is_jmp = DISAS_NORETURN;
}
} else if (ctx->le_mode) {
tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ);
gen_addr_add(ctx, EA, EA, 8);
tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ);
} else {
tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ);
gen_addr_add(ctx, EA, EA, 8);
tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ);
}
tcg_temp_free(EA);
}
#endif #endif
/*** Integer store ***/ /*** Integer store ***/
@ -3435,90 +3372,6 @@ GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST) GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST) GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST) GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
static void gen_std(DisasContext *ctx)
{
int rs;
TCGv EA;
rs = rS(ctx->opcode);
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;
TCGv hi, lo;
if (!(ctx->insns_flags & PPC_64BX)) {
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
}
if (!legal_in_user_mode && ctx->pr) {
gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
if (!le_is_supported && ctx->le_mode) {
gen_align_no_le(ctx);
return;
}
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);
/* Note that the low part is always in RS+1, even in LE mode. */
lo = cpu_gpr[rs + 1];
hi = cpu_gpr[rs];
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
if (HAVE_ATOMIC128) {
TCGv_i32 oi = tcg_temp_new_i32();
if (ctx->le_mode) {
tcg_gen_movi_i32(oi, make_memop_idx(MO_LE | MO_128,
ctx->mem_idx));
gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi);
} else {
tcg_gen_movi_i32(oi, make_memop_idx(MO_BE | MO_128,
ctx->mem_idx));
gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi);
}
tcg_temp_free_i32(oi);
} else {
/* Restart with exclusive lock. */
gen_helper_exit_atomic(cpu_env);
ctx->base.is_jmp = DISAS_NORETURN;
}
} else if (ctx->le_mode) {
tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_LEQ);
gen_addr_add(ctx, EA, EA, 8);
tcg_gen_qemu_st_i64(hi, EA, ctx->mem_idx, MO_LEQ);
} else {
tcg_gen_qemu_st_i64(hi, EA, ctx->mem_idx, MO_BEQ);
gen_addr_add(ctx, EA, EA, 8);
tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_BEQ);
}
tcg_temp_free(EA);
} else {
/* std / stdu */
if (Rc(ctx->opcode)) {
if (unlikely(rA(ctx->opcode) == 0)) {
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_i64(ctx, cpu_gpr[rs], EA);
if (Rc(ctx->opcode)) {
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
}
tcg_temp_free(EA);
}
}
#endif #endif
/*** Integer load and store with byte reverse ***/ /*** Integer load and store with byte reverse ***/
@ -7457,6 +7310,11 @@ static int times_4(DisasContext *ctx, int x)
return x * 4; return x * 4;
} }
static int times_16(DisasContext *ctx, int x)
{
return x * 16;
}
/* /*
* Helpers for trans_* functions to check for specific insns flags. * Helpers for trans_* functions to check for specific insns flags.
* Use token pasting to ensure that we use the proper flag with the * Use token pasting to ensure that we use the proper flag with the
@ -7696,10 +7554,6 @@ GEN_HANDLER2_E(extswsli0, "extswsli", 0x1F, 0x1A, 0x1B, 0x00000000,
GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000, GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000,
PPC_NONE, PPC2_ISA300), PPC_NONE, PPC2_ISA300),
#endif #endif
#if defined(TARGET_PPC64)
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
#endif
/* handles lfdp, lxsd, lxssp */ /* handles lfdp, lxsd, lxssp */
GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205), GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
/* handles stfdp, lxv, stxsd, stxssp, stxv */ /* handles stfdp, lxv, stxsd, stxssp, stxv */

View File

@ -69,6 +69,97 @@ static bool do_ldst_X(DisasContext *ctx, arg_X *a, bool update,
return do_ldst(ctx, a->rt, a->ra, cpu_gpr[a->rb], update, store, mop); return do_ldst(ctx, a->rt, a->ra, cpu_gpr[a->rb], update, store, mop);
} }
static bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed)
{
#if defined(TARGET_PPC64)
TCGv ea;
TCGv_i64 low_addr_gpr, high_addr_gpr;
MemOp mop;
REQUIRE_INSNS_FLAGS(ctx, 64BX);
if (!prefixed && !(ctx->insns_flags2 & PPC2_LSQ_ISA207)) {
if (ctx->pr) {
/* lq and stq were privileged prior to V. 2.07 */
gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return true;
}
if (ctx->le_mode) {
gen_align_no_le(ctx);
return true;
}
}
if (!store && unlikely(a->ra == a->rt)) {
gen_invalid(ctx);
return true;
}
gen_set_access_type(ctx, ACCESS_INT);
ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->si));
if (prefixed || !ctx->le_mode) {
low_addr_gpr = cpu_gpr[a->rt];
high_addr_gpr = cpu_gpr[a->rt + 1];
} else {
low_addr_gpr = cpu_gpr[a->rt + 1];
high_addr_gpr = cpu_gpr[a->rt];
}
if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
if (HAVE_ATOMIC128) {
mop = DEF_MEMOP(MO_128);
TCGv_i32 oi = tcg_constant_i32(make_memop_idx(mop, ctx->mem_idx));
if (store) {
if (ctx->le_mode) {
gen_helper_stq_le_parallel(cpu_env, ea, low_addr_gpr,
high_addr_gpr, oi);
} else {
gen_helper_stq_be_parallel(cpu_env, ea, high_addr_gpr,
low_addr_gpr, oi);
}
} else {
if (ctx->le_mode) {
gen_helper_lq_le_parallel(low_addr_gpr, cpu_env, ea, oi);
tcg_gen_ld_i64(high_addr_gpr, cpu_env,
offsetof(CPUPPCState, retxh));
} else {
gen_helper_lq_be_parallel(high_addr_gpr, cpu_env, ea, oi);
tcg_gen_ld_i64(low_addr_gpr, cpu_env,
offsetof(CPUPPCState, retxh));
}
}
} else {
/* Restart with exclusive lock. */
gen_helper_exit_atomic(cpu_env);
ctx->base.is_jmp = DISAS_NORETURN;
}
} else {
mop = DEF_MEMOP(MO_Q);
if (store) {
tcg_gen_qemu_st_i64(low_addr_gpr, ea, ctx->mem_idx, mop);
} else {
tcg_gen_qemu_ld_i64(low_addr_gpr, ea, ctx->mem_idx, mop);
}
gen_addr_add(ctx, ea, ea, 8);
if (store) {
tcg_gen_qemu_st_i64(high_addr_gpr, ea, ctx->mem_idx, mop);
} else {
tcg_gen_qemu_ld_i64(high_addr_gpr, ea, ctx->mem_idx, mop);
}
}
tcg_temp_free(ea);
#else
qemu_build_not_reached();
#endif
return true;
}
/* Load Byte and Zero */ /* Load Byte and Zero */
TRANS(LBZ, do_ldst_D, false, false, MO_UB) TRANS(LBZ, do_ldst_D, false, false, MO_UB)
TRANS(LBZX, do_ldst_X, false, false, MO_UB) TRANS(LBZX, do_ldst_X, false, false, MO_UB)
@ -110,6 +201,9 @@ TRANS64(LDU, do_ldst_D, true, false, MO_Q)
TRANS64(LDUX, do_ldst_X, true, false, MO_Q) TRANS64(LDUX, do_ldst_X, true, false, MO_Q)
TRANS64(PLD, do_ldst_PLS_D, false, false, MO_Q) TRANS64(PLD, do_ldst_PLS_D, false, false, MO_Q)
/* Load Quadword */
TRANS64(LQ, do_ldst_quad, false, false);
/* Store Byte */ /* Store Byte */
TRANS(STB, do_ldst_D, false, true, MO_UB) TRANS(STB, do_ldst_D, false, true, MO_UB)
TRANS(STBX, do_ldst_X, false, true, MO_UB) TRANS(STBX, do_ldst_X, false, true, MO_UB)
@ -138,6 +232,9 @@ TRANS64(STDU, do_ldst_D, true, true, MO_Q)
TRANS64(STDUX, do_ldst_X, true, true, MO_Q) TRANS64(STDUX, do_ldst_X, true, true, MO_Q)
TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_Q) TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_Q)
/* Store Quadword */
TRANS64(STQ, do_ldst_quad, true, false);
/* /*
* Fixed-Point Compare Instructions * Fixed-Point Compare Instructions
*/ */