diff mbox series

[v3,1/2] target/ppc: Move tlbie[l] to decode tree

Message ID 20220712193741.59134-2-leandro.lupori@eldorado.org.br
State New
Headers show
Series target/ppc: Implement ISA 3.00 tlbie[l] | expand

Commit Message

Leandro Lupori July 12, 2022, 7:37 p.m. UTC
Also decode RIC, PRS and R operands.

Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
---
 target/ppc/cpu_init.c                        |  4 +-
 target/ppc/insn32.decode                     |  8 ++
 target/ppc/translate.c                       | 64 +-------------
 target/ppc/translate/storage-ctrl-impl.c.inc | 87 ++++++++++++++++++++
 4 files changed, 99 insertions(+), 64 deletions(-)
 create mode 100644 target/ppc/translate/storage-ctrl-impl.c.inc

Comments

Daniel Henrique Barboza July 14, 2022, 6:45 p.m. UTC | #1
On 7/12/22 16:37, Leandro Lupori wrote:
> Also decode RIC, PRS and R operands.
> 
> Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
> ---
>   target/ppc/cpu_init.c                        |  4 +-
>   target/ppc/insn32.decode                     |  8 ++
>   target/ppc/translate.c                       | 64 +-------------
>   target/ppc/translate/storage-ctrl-impl.c.inc | 87 ++++++++++++++++++++
>   4 files changed, 99 insertions(+), 64 deletions(-)
>   create mode 100644 target/ppc/translate/storage-ctrl-impl.c.inc
> 
> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
> index c16cb8dbe7..8d7e77f778 100644
> --- a/target/ppc/cpu_init.c
> +++ b/target/ppc/cpu_init.c
> @@ -6368,7 +6368,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>                          PPC_FLOAT_EXT |
>                          PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>                          PPC_MEM_SYNC | PPC_MEM_EIEIO |
> -                       PPC_MEM_TLBSYNC |
> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>                          PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>                          PPC_SEGMENT_64B | PPC_SLBI |
>                          PPC_POPCNTB | PPC_POPCNTWD |
> @@ -6585,7 +6585,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
>                          PPC_FLOAT_EXT |
>                          PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>                          PPC_MEM_SYNC | PPC_MEM_EIEIO |
> -                       PPC_MEM_TLBSYNC |
> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>                          PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>                          PPC_SEGMENT_64B | PPC_SLBI |
>                          PPC_POPCNTB | PPC_POPCNTWD |
> diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
> index 6ea48d5163..2b985249b8 100644
> --- a/target/ppc/insn32.decode
> +++ b/target/ppc/insn32.decode
> @@ -809,3 +809,11 @@ VMODSD          000100 ..... ..... ..... 11111001011    @VX
>   VMODUD          000100 ..... ..... ..... 11011001011    @VX
>   VMODSQ          000100 ..... ..... ..... 11100001011    @VX
>   VMODUQ          000100 ..... ..... ..... 11000001011    @VX
> +
> +## TLB Management Instructions
> +
> +&X_tlbie        rb rs ric prs:bool r:bool
> +@X_tlbie        ...... rs:5 - ric:2 prs:1 r:1 rb:5 .......... .     &X_tlbie

You're marking bit 11 as ignored but you're not marking 31 as ignored. The way
the argument patterns are made in this file seems to be either not mark the
ignored bits (e.g. most of args from the start of the file) or mark all ignore
bits (e.g. @XL_S from RFEBB).

I am being petty, yes. This makes no functional change in the instruction, but
I'd rather mark bit 31 as ignored in @X_tlbie as well.

I did that in my tree and it seems to work fine. If you're ok with this change,



Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>



> +
> +TLBIE           011111 ..... - .. . . ..... 0100110010 -            @X_tlbie
> +TLBIEL          011111 ..... - .. . . ..... 0100010010 -            @X_tlbie
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 1d6daa4608..4fcb311c2d 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -5424,64 +5424,6 @@ static void gen_tlbia(DisasContext *ctx)
>   #endif  /* defined(CONFIG_USER_ONLY) */
>   }
>   
> -/* tlbiel */
> -static void gen_tlbiel(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV;
> -#else
> -    bool psr = (ctx->opcode >> 17) & 0x1;
> -
> -    if (ctx->pr || (!ctx->hv && !psr && ctx->hr)) {
> -        /*
> -         * tlbiel is privileged except when PSR=0 and HR=1, making it
> -         * hypervisor privileged.
> -         */
> -        GEN_PRIV;
> -    }
> -
> -    gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
> -/* tlbie */
> -static void gen_tlbie(DisasContext *ctx)
> -{
> -#if defined(CONFIG_USER_ONLY)
> -    GEN_PRIV;
> -#else
> -    bool psr = (ctx->opcode >> 17) & 0x1;
> -    TCGv_i32 t1;
> -
> -    if (ctx->pr) {
> -        /* tlbie is privileged... */
> -        GEN_PRIV;
> -    } else if (!ctx->hv) {
> -        if (!ctx->gtse || (!psr && ctx->hr)) {
> -            /*
> -             * ... except when GTSE=0 or when PSR=0 and HR=1, making it
> -             * hypervisor privileged.
> -             */
> -            GEN_PRIV;
> -        }
> -    }
> -
> -    if (NARROW_MODE(ctx)) {
> -        TCGv t0 = tcg_temp_new();
> -        tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
> -        gen_helper_tlbie(cpu_env, t0);
> -        tcg_temp_free(t0);
> -    } else {
> -        gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
> -    }
> -    t1 = tcg_temp_new_i32();
> -    tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
> -    tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
> -    tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
> -    tcg_temp_free_i32(t1);
> -#endif /* defined(CONFIG_USER_ONLY) */
> -}
> -
>   /* tlbsync */
>   static void gen_tlbsync(DisasContext *ctx)
>   {
> @@ -6699,6 +6641,8 @@ static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a)
>   
>   #include "translate/branch-impl.c.inc"
>   
> +#include "translate/storage-ctrl-impl.c.inc"
> +
>   /* Handles lfdp */
>   static void gen_dform39(DisasContext *ctx)
>   {
> @@ -6937,10 +6881,6 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
>    * XXX Those instructions will need to be handled differently for
>    * different ISA versions
>    */
> -GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
> -GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
> -GEN_HANDLER_E(tlbiel, 0x1F, 0x12, 0x08, 0x00100001, PPC_NONE, PPC2_ISA300),
> -GEN_HANDLER_E(tlbie, 0x1F, 0x12, 0x09, 0x00100001, PPC_NONE, PPC2_ISA300),
>   GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
>   #if defined(TARGET_PPC64)
>   GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
> diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc
> new file mode 100644
> index 0000000000..7793297dd4
> --- /dev/null
> +++ b/target/ppc/translate/storage-ctrl-impl.c.inc
> @@ -0,0 +1,87 @@
> +/*
> + * Power ISA decode for Storage Control instructions
> + *
> + * Copyright (c) 2022 Instituto de Pesquisas Eldorado (eldorado.org.br)
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/*
> + * Store Control Instructions
> + */
> +
> +static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local)
> +{
> +#if defined(CONFIG_USER_ONLY)
> +    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +    return true;
> +#else
> +    TCGv_i32 t1;
> +    int rb;
> +
> +    rb = a->rb;
> +
> +    if ((ctx->insns_flags2 & PPC2_ISA300) == 0) {
> +        /*
> +         * Before Power ISA 3.0, the corresponding bits of RIC, PRS, and R
> +         * (and RS for tlbiel) were reserved fields and should be ignored.
> +         */
> +        a->ric = 0;
> +        a->prs = false;
> +        a->r = false;
> +        if (local) {
> +            a->rs = 0;
> +        }
> +    }
> +
> +    if (ctx->pr) {
> +        /* tlbie[l] is privileged... */
> +        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +        return true;
> +    } else if (!ctx->hv) {
> +        if ((!a->prs && ctx->hr) || (!local && !ctx->gtse)) {
> +            /*
> +             * ... except when PRS=0 and HR=1, or when GTSE=0 for tlbie,
> +             * making it hypervisor privileged.
> +             */
> +            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
> +            return true;
> +        }
> +    }
> +
> +    if (!local && NARROW_MODE(ctx)) {
> +        TCGv t0 = tcg_temp_new();
> +        tcg_gen_ext32u_tl(t0, cpu_gpr[rb]);
> +        gen_helper_tlbie(cpu_env, t0);
> +        tcg_temp_free(t0);
> +    } else {
> +        gen_helper_tlbie(cpu_env, cpu_gpr[rb]);
> +    }
> +
> +    if (local) {
> +        return true;
> +    }
> +
> +    t1 = tcg_temp_new_i32();
> +    tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
> +    tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
> +    tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
> +    tcg_temp_free_i32(t1);
> +
> +    return true;
> +#endif
> +}
> +
> +TRANS_FLAGS(MEM_TLBIE, TLBIE, do_tlbie, false)
> +TRANS_FLAGS(MEM_TLBIE, TLBIEL, do_tlbie, true)
Leandro Lupori July 14, 2022, 7:31 p.m. UTC | #2
On 7/14/22 15:45, Daniel Henrique Barboza wrote:
> On 7/12/22 16:37, Leandro Lupori wrote:
>> Also decode RIC, PRS and R operands.
>>
>> Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
>> ---
>>   target/ppc/cpu_init.c                        |  4 +-
>>   target/ppc/insn32.decode                     |  8 ++
>>   target/ppc/translate.c                       | 64 +-------------
>>   target/ppc/translate/storage-ctrl-impl.c.inc | 87 ++++++++++++++++++++
>>   4 files changed, 99 insertions(+), 64 deletions(-)
>>   create mode 100644 target/ppc/translate/storage-ctrl-impl.c.inc
>>
>> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
>> index c16cb8dbe7..8d7e77f778 100644
>> --- a/target/ppc/cpu_init.c
>> +++ b/target/ppc/cpu_init.c
>> @@ -6368,7 +6368,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>>                          PPC_FLOAT_EXT |
>>                          PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>>                          PPC_MEM_SYNC | PPC_MEM_EIEIO |
>> -                       PPC_MEM_TLBSYNC |
>> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>>                          PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>>                          PPC_SEGMENT_64B | PPC_SLBI |
>>                          PPC_POPCNTB | PPC_POPCNTWD |
>> @@ -6585,7 +6585,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void 
>> *data)
>>                          PPC_FLOAT_EXT |
>>                          PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>>                          PPC_MEM_SYNC | PPC_MEM_EIEIO |
>> -                       PPC_MEM_TLBSYNC |
>> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>>                          PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>>                          PPC_SEGMENT_64B | PPC_SLBI |
>>                          PPC_POPCNTB | PPC_POPCNTWD |
>> diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
>> index 6ea48d5163..2b985249b8 100644
>> --- a/target/ppc/insn32.decode
>> +++ b/target/ppc/insn32.decode
>> @@ -809,3 +809,11 @@ VMODSD          000100 ..... ..... ..... 
>> 11111001011    @VX
>>   VMODUD          000100 ..... ..... ..... 11011001011    @VX
>>   VMODSQ          000100 ..... ..... ..... 11100001011    @VX
>>   VMODUQ          000100 ..... ..... ..... 11000001011    @VX
>> +
>> +## TLB Management Instructions
>> +
>> +&X_tlbie        rb rs ric prs:bool r:bool
>> +@X_tlbie        ...... rs:5 - ric:2 prs:1 r:1 rb:5 .......... .     
>> &X_tlbie
> 
> You're marking bit 11 as ignored but you're not marking 31 as ignored. 
> The way
> the argument patterns are made in this file seems to be either not mark the
> ignored bits (e.g. most of args from the start of the file) or mark all 
> ignore
> bits (e.g. @XL_S from RFEBB).
> 
> I am being petty, yes. This makes no functional change in the 
> instruction, but
> I'd rather mark bit 31 as ignored in @X_tlbie as well.
> 
> I did that in my tree and it seems to work fine. If you're ok with this 
> change,
> 
> 
> 
> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> 

Right, the @X_tlbie pattern ended up inconsistent with regard to ignored 
bits. I'm ok with changing bit 31 of it to ignored.

Talking with the guys here, they've explained me that it is usually 
better to use '.' with format definitions ('@'), to make it easier to 
reuse them for more instructions, some of which may ignore a given bit 
while others may not. But for @X_tlbie it's ok to use dots or dashes for 
bits 11 and 31, as it's used only by TLBIE and TLBIEL.

Thanks,
Leandro

> 
> 
>> +
>> +TLBIE           011111 ..... - .. . . ..... 0100110010 -            
>> @X_tlbie
>> +TLBIEL          011111 ..... - .. . . ..... 0100010010 -            
>> @X_tlbie
Daniel Henrique Barboza July 14, 2022, 7:36 p.m. UTC | #3
On 7/14/22 16:31, Leandro Lupori wrote:
> On 7/14/22 15:45, Daniel Henrique Barboza wrote:
>> On 7/12/22 16:37, Leandro Lupori wrote:
>>> Also decode RIC, PRS and R operands.
>>>
>>> Signed-off-by: Leandro Lupori <leandro.lupori@eldorado.org.br>
>>> ---
>>>   target/ppc/cpu_init.c                        |  4 +-
>>>   target/ppc/insn32.decode                     |  8 ++
>>>   target/ppc/translate.c                       | 64 +-------------
>>>   target/ppc/translate/storage-ctrl-impl.c.inc | 87 ++++++++++++++++++++
>>>   4 files changed, 99 insertions(+), 64 deletions(-)
>>>   create mode 100644 target/ppc/translate/storage-ctrl-impl.c.inc
>>>
>>> diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
>>> index c16cb8dbe7..8d7e77f778 100644
>>> --- a/target/ppc/cpu_init.c
>>> +++ b/target/ppc/cpu_init.c
>>> @@ -6368,7 +6368,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
>>>                          PPC_FLOAT_EXT |
>>>                          PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>>>                          PPC_MEM_SYNC | PPC_MEM_EIEIO |
>>> -                       PPC_MEM_TLBSYNC |
>>> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>>>                          PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>>>                          PPC_SEGMENT_64B | PPC_SLBI |
>>>                          PPC_POPCNTB | PPC_POPCNTWD |
>>> @@ -6585,7 +6585,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
>>>                          PPC_FLOAT_EXT |
>>>                          PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
>>>                          PPC_MEM_SYNC | PPC_MEM_EIEIO |
>>> -                       PPC_MEM_TLBSYNC |
>>> +                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
>>>                          PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
>>>                          PPC_SEGMENT_64B | PPC_SLBI |
>>>                          PPC_POPCNTB | PPC_POPCNTWD |
>>> diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
>>> index 6ea48d5163..2b985249b8 100644
>>> --- a/target/ppc/insn32.decode
>>> +++ b/target/ppc/insn32.decode
>>> @@ -809,3 +809,11 @@ VMODSD          000100 ..... ..... ..... 11111001011    @VX
>>>   VMODUD          000100 ..... ..... ..... 11011001011    @VX
>>>   VMODSQ          000100 ..... ..... ..... 11100001011    @VX
>>>   VMODUQ          000100 ..... ..... ..... 11000001011    @VX
>>> +
>>> +## TLB Management Instructions
>>> +
>>> +&X_tlbie        rb rs ric prs:bool r:bool
>>> +@X_tlbie        ...... rs:5 - ric:2 prs:1 r:1 rb:5 .......... . &X_tlbie
>>
>> You're marking bit 11 as ignored but you're not marking 31 as ignored. The way
>> the argument patterns are made in this file seems to be either not mark the
>> ignored bits (e.g. most of args from the start of the file) or mark all ignore
>> bits (e.g. @XL_S from RFEBB).
>>
>> I am being petty, yes. This makes no functional change in the instruction, but
>> I'd rather mark bit 31 as ignored in @X_tlbie as well.
>>
>> I did that in my tree and it seems to work fine. If you're ok with this change,
>>
>>
>>
>> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
>>
> 
> Right, the @X_tlbie pattern ended up inconsistent with regard to ignored bits. I'm ok with changing bit 31 of it to ignored.
> 
> Talking with the guys here, they've explained me that it is usually better to use '.' with format definitions ('@'), to make it easier to reuse them for more instructions, some of which may ignore a given bit while others may not. But for @X_tlbie it's ok to use dots or dashes for bits 11 and 31, as it's used only by TLBIE and TLBIEL.


Makes sense. Thanks for the explanation. I'll keep that in mind.


Daniel


> 
> Thanks,
> Leandro
> 
>>
>>
>>> +
>>> +TLBIE           011111 ..... - .. . . ..... 0100110010 - @X_tlbie
>>> +TLBIEL          011111 ..... - .. . . ..... 0100010010 - @X_tlbie
diff mbox series

Patch

diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index c16cb8dbe7..8d7e77f778 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -6368,7 +6368,7 @@  POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
                        PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
-                       PPC_MEM_TLBSYNC |
+                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD |
@@ -6585,7 +6585,7 @@  POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
                        PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
-                       PPC_MEM_TLBSYNC |
+                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
                        PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD |
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6ea48d5163..2b985249b8 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -809,3 +809,11 @@  VMODSD          000100 ..... ..... ..... 11111001011    @VX
 VMODUD          000100 ..... ..... ..... 11011001011    @VX
 VMODSQ          000100 ..... ..... ..... 11100001011    @VX
 VMODUQ          000100 ..... ..... ..... 11000001011    @VX
+
+## TLB Management Instructions
+
+&X_tlbie        rb rs ric prs:bool r:bool
+@X_tlbie        ...... rs:5 - ric:2 prs:1 r:1 rb:5 .......... .     &X_tlbie
+
+TLBIE           011111 ..... - .. . . ..... 0100110010 -            @X_tlbie
+TLBIEL          011111 ..... - .. . . ..... 0100010010 -            @X_tlbie
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 1d6daa4608..4fcb311c2d 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -5424,64 +5424,6 @@  static void gen_tlbia(DisasContext *ctx)
 #endif  /* defined(CONFIG_USER_ONLY) */
 }
 
-/* tlbiel */
-static void gen_tlbiel(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    bool psr = (ctx->opcode >> 17) & 0x1;
-
-    if (ctx->pr || (!ctx->hv && !psr && ctx->hr)) {
-        /*
-         * tlbiel is privileged except when PSR=0 and HR=1, making it
-         * hypervisor privileged.
-         */
-        GEN_PRIV;
-    }
-
-    gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbie */
-static void gen_tlbie(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
-    GEN_PRIV;
-#else
-    bool psr = (ctx->opcode >> 17) & 0x1;
-    TCGv_i32 t1;
-
-    if (ctx->pr) {
-        /* tlbie is privileged... */
-        GEN_PRIV;
-    } else if (!ctx->hv) {
-        if (!ctx->gtse || (!psr && ctx->hr)) {
-            /*
-             * ... except when GTSE=0 or when PSR=0 and HR=1, making it
-             * hypervisor privileged.
-             */
-            GEN_PRIV;
-        }
-    }
-
-    if (NARROW_MODE(ctx)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
-        gen_helper_tlbie(cpu_env, t0);
-        tcg_temp_free(t0);
-    } else {
-        gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-    }
-    t1 = tcg_temp_new_i32();
-    tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
-    tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
-    tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
-    tcg_temp_free_i32(t1);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
 /* tlbsync */
 static void gen_tlbsync(DisasContext *ctx)
 {
@@ -6699,6 +6641,8 @@  static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a)
 
 #include "translate/branch-impl.c.inc"
 
+#include "translate/storage-ctrl-impl.c.inc"
+
 /* Handles lfdp */
 static void gen_dform39(DisasContext *ctx)
 {
@@ -6937,10 +6881,6 @@  GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
  * XXX Those instructions will need to be handled differently for
  * different ISA versions
  */
-GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
-GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
-GEN_HANDLER_E(tlbiel, 0x1F, 0x12, 0x08, 0x00100001, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(tlbie, 0x1F, 0x12, 0x09, 0x00100001, PPC_NONE, PPC2_ISA300),
 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc
new file mode 100644
index 0000000000..7793297dd4
--- /dev/null
+++ b/target/ppc/translate/storage-ctrl-impl.c.inc
@@ -0,0 +1,87 @@ 
+/*
+ * Power ISA decode for Storage Control instructions
+ *
+ * Copyright (c) 2022 Instituto de Pesquisas Eldorado (eldorado.org.br)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Store Control Instructions
+ */
+
+static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+    return true;
+#else
+    TCGv_i32 t1;
+    int rb;
+
+    rb = a->rb;
+
+    if ((ctx->insns_flags2 & PPC2_ISA300) == 0) {
+        /*
+         * Before Power ISA 3.0, the corresponding bits of RIC, PRS, and R
+         * (and RS for tlbiel) were reserved fields and should be ignored.
+         */
+        a->ric = 0;
+        a->prs = false;
+        a->r = false;
+        if (local) {
+            a->rs = 0;
+        }
+    }
+
+    if (ctx->pr) {
+        /* tlbie[l] is privileged... */
+        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return true;
+    } else if (!ctx->hv) {
+        if ((!a->prs && ctx->hr) || (!local && !ctx->gtse)) {
+            /*
+             * ... except when PRS=0 and HR=1, or when GTSE=0 for tlbie,
+             * making it hypervisor privileged.
+             */
+            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+            return true;
+        }
+    }
+
+    if (!local && NARROW_MODE(ctx)) {
+        TCGv t0 = tcg_temp_new();
+        tcg_gen_ext32u_tl(t0, cpu_gpr[rb]);
+        gen_helper_tlbie(cpu_env, t0);
+        tcg_temp_free(t0);
+    } else {
+        gen_helper_tlbie(cpu_env, cpu_gpr[rb]);
+    }
+
+    if (local) {
+        return true;
+    }
+
+    t1 = tcg_temp_new_i32();
+    tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
+    tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
+    tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
+    tcg_temp_free_i32(t1);
+
+    return true;
+#endif
+}
+
+TRANS_FLAGS(MEM_TLBIE, TLBIE, do_tlbie, false)
+TRANS_FLAGS(MEM_TLBIE, TLBIEL, do_tlbie, true)