[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/7] target/ppc: Add support for prefixed load/store instruct
From: |
David Gibson |
Subject: |
Re: [PATCH 2/7] target/ppc: Add support for prefixed load/store instructions |
Date: |
Fri, 9 Oct 2020 11:50:10 +1100 |
On Mon, Oct 05, 2020 at 01:03:14AM -0300, Gustavo Romero wrote:
> From: Michael Roth <mdroth@linux.vnet.ibm.com>
>
> This commit adds support for the following prefixed load and store
> instructions for GPRs:
>
> plbz, plh{a,z}, plw{a,z}, pld, plq
> pstb, psth, pstw, pstd, pstq
> paddi
Are there architecture docs publically available yet which describe
these instructions?
> Signed-off-by: Michael Roth <mroth@lamentation.net>
> [ gromero: - fix for gen_addr_imm34_index()
> - removed redundant PREFIX_R bit helper
> - changes in commit log ]
> Signed-off-by: Gustavo Romero <gromero@linux.ibm.com>
> ---
> target/ppc/internal.h | 6 +
> target/ppc/translate.c | 259 +++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 265 insertions(+)
>
> diff --git a/target/ppc/internal.h b/target/ppc/internal.h
> index d03d691a44..dc4aff863c 100644
> --- a/target/ppc/internal.h
> +++ b/target/ppc/internal.h
> @@ -159,6 +159,12 @@ EXTRACT_HELPER(PREFIX_TYPE, 24, 2);
> EXTRACT_HELPER(PREFIX_ST1, 23, 1);
> /* 4-bit sub-type */
> EXTRACT_HELPER(PREFIX_ST4, 20, 4);
> +/* 18 bits signed immediate value */
> +EXTRACT_SHELPER(SIMM18, 0, 18);
> +/* 18 bits unsigned immediate value */
> +EXTRACT_HELPER(UIMM18, 0, 18);
> +/* relative to CIA (current instruction address) */
> +EXTRACT_HELPER(R, 20, 1);
>
> #ifndef CONFIG_USER_ONLY
> EXTRACT_HELPER(SR, 16, 4);
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 96c2997d3f..82376b50ff 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -2495,6 +2495,34 @@ static inline void gen_addr_add(DisasContext *ctx,
> TCGv ret, TCGv arg1,
> }
> }
>
> +/* returns false if exception was generated */
Probably better to return a bool, then.
> +static inline int gen_addr_imm34_index(DisasContext *ctx, TCGv EA)
> +{
> + uint64_t offset;
> +
> + if (R(ctx->prefix) == 1) {
I'm having trouble tracking down this 'R' macro to work out what
that's doing.
> + if (unlikely(rA(ctx->opcode) != 0)) {
> + gen_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> + return 1;
> + }
> + // To find out the address of a prefixed instruction
> + // it's necessary to rewind 8 bytes because they are
> + // twice the size of non-prefixed instructions.
> + tcg_gen_movi_tl(EA, ctx->base.pc_next - 8);
> + } else {
> + gen_addr_register(ctx, EA);
> + }
> +
> + offset = (uint64_t)UIMM18(ctx->prefix) << 16;
> + offset |= UIMM(ctx->opcode);
> + /* sign-extend 34 bit offset to 64-bits... */
> + if (extract64(offset, 33, 1) == 1) {
> + offset |= -1UL << 34;
> + }
> + tcg_gen_addi_tl(EA, EA, offset);
> + return 0;
> +}
> +
> static inline void gen_align_no_le(DisasContext *ctx)
> {
> gen_exception_err(ctx, POWERPC_EXCP_ALIGN,
> @@ -2714,6 +2742,35 @@ static void gen_ld(DisasContext *ctx)
> tcg_temp_free(EA);
> }
>
> +static void gen_pld(DisasContext *ctx)
> +{
> + TCGv EA;
> +
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld64_i64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +/* paddi */
> +static void gen_paddi(DisasContext *ctx)
> +{
> + TCGv EA;
> +
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld64_i64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +
> +out:
> + tcg_temp_free(EA);
> +}
> +
> /* lq */
> static void gen_lq(DisasContext *ctx)
> {
> @@ -2776,6 +2833,195 @@ static void gen_lq(DisasContext *ctx)
> }
> tcg_temp_free(EA);
> }
> +
> +static void gen_plq(DisasContext *ctx)
> +{
> + int ra, rd;
> + TCGv EA, rd0, rd1;
> +
> + 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();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> +
> + rd0 = cpu_gpr[rd];
> + rd1 = cpu_gpr[rd + 1];
> +
> + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
> + /* Restart with exclusive lock. */
> + gen_helper_exit_atomic(cpu_env);
> + ctx->base.is_jmp = DISAS_NORETURN;
> + } else {
> + tcg_gen_qemu_ld_i64(rd0, EA, ctx->mem_idx,
> + ctx->le_mode ? MO_LEQ : MO_BEQ);
> + gen_addr_add(ctx, EA, EA, 8);
> + tcg_gen_qemu_ld_i64(rd1, EA, ctx->mem_idx,
> + ctx->le_mode ? MO_LEQ : MO_BEQ);
> + }
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_plbz(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld8u(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_plhz(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_plha(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_plwz(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_plwa(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_pstb(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_st8(ctx, cpu_gpr[rS(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_psth(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_pstw(DisasContext *ctx)
> +{
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_pstd(DisasContext *ctx) {
> + TCGv EA;
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> + gen_qemu_st64_i64(ctx, cpu_gpr[rS(ctx->opcode)], EA);
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +static void gen_pstq(DisasContext *ctx) {
> + int ra, rs;
> + TCGv EA, rs0, rs1;
> +
> + ra = rA(ctx->opcode);
> + rs = rD(ctx->opcode);
> + if (unlikely((rs & 1) || rs == ra)) {
> + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
> + return;
> + }
> +
> + gen_set_access_type(ctx, ACCESS_INT);
> + EA = tcg_temp_new();
> + if (gen_addr_imm34_index(ctx, EA)) {
> + goto out;
> + }
> +
> + rs0 = cpu_gpr[rs];
> + rs1 = cpu_gpr[rs + 1];
> +
> + if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
> + /* Restart with exclusive lock. */
> + gen_helper_exit_atomic(cpu_env);
> + ctx->base.is_jmp = DISAS_NORETURN;
> + } else {
> + tcg_gen_qemu_st_i64(rs0, EA, ctx->mem_idx,
> + ctx->le_mode ? MO_LEQ : MO_BEQ);
> + gen_addr_add(ctx, EA, EA, 8);
> + tcg_gen_qemu_st_i64(rs1, EA, ctx->mem_idx,
> + ctx->le_mode ? MO_LEQ : MO_BEQ);
> + }
> +out:
> + tcg_temp_free(EA);
> +}
> +
> +
> #endif
>
> /*** Integer store
> ***/
> @@ -7067,6 +7313,7 @@ GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001,
> PPC_NONE, PPC2_ISA205),
> GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300),
> GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
> GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
> +GEN_HANDLER_E_PREFIXED_M(paddi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
> GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
> GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
> @@ -7128,6 +7375,18 @@ GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B,
> 0x1B, 0x00000000,
> GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
> GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
> GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
> +GEN_HANDLER_E_PREFIXED_M(plbz, 0x22, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED_M(plhz, 0x28, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED_M(plha, 0x2a, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED_M(plwz, 0x20, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED(plwa, 0x29, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED(pld, 0x39, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED(plq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED_M(pstb, 0x26, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED_M(psth, 0x2c, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED_M(pstw, 0x24, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED(pstd, 0x3d, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> +GEN_HANDLER_E_PREFIXED(pstq, 0x3c, 0xFF, 0xFF, 0x00000000, PPC_64B,
> PPC2_ISA310),
> #endif
> /* handles lfdp, lxsd, lxssp */
> GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature
- [PATCH 1/7] target/ppc: Add infrastructure for prefixed instructions, Gustavo Romero, 2020/10/05
- [PATCH 3/7] tests/tcg: Add tests for prefixed load/store instructions, Gustavo Romero, 2020/10/05
- [PATCH 4/7] target/ppc: Add support for paired vector load/store instructions, Gustavo Romero, 2020/10/05
- [PATCH 5/7] tests/tcg: Add tests for paired vector load/store instructions, Gustavo Romero, 2020/10/05
- [PATCH 6/7] target/ppc: Add support for prefixed load/store FP instructions, Gustavo Romero, 2020/10/05
- [PATCH 7/7] tests/tcg: Add tests for prefixed load/store FP instructions, Gustavo Romero, 2020/10/05
- Re: [PATCH 1/7] target/ppc: Add infrastructure for prefixed instructions, David Gibson, 2020/10/08