diff mbox series

[1/4] target/ppc: Add new hflags to support BHRB

Message ID 20230912202347.3381298-1-milesg@linux.vnet.ibm.com
State New
Headers show
Series Add BHRB Facility Support | expand

Commit Message

Glenn Miles Sept. 12, 2023, 8:23 p.m. UTC
This commit is preparatory to the addition of Branch History
Rolling Buffer (BHRB) functionality, which is being provided
today starting with the P8 processor.

BHRB uses several SPR register fields to control whether or not
a branch instruction's address (and sometimes target address)
should be recorded.  Checking each of these fields with each
branch instruction using jitted code would lead to a significant
decrease in performance.

Therefore, it was decided that BHRB configuration bits that are
not expected to change frequently should have their state stored in
hflags so that the amount of checking done by jitted code can
be reduced.

This commit contains the changes for storing the state of the
following register fields as hflags:

	MMCR0[FCP] - Determines if BHRB recording is frozen in the
                     problem state

	MMCR0[FCPC] - A modifier for MMCR0[FCP]

	MMCRA[BHRBRD] - Disables all BHRB recording for a thread

Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
---
 target/ppc/cpu.h                 |  9 +++++++++
 target/ppc/cpu_init.c            |  4 ++--
 target/ppc/helper.h              |  1 +
 target/ppc/helper_regs.c         | 12 ++++++++++++
 target/ppc/machine.c             |  2 +-
 target/ppc/power8-pmu-regs.c.inc |  5 +++++
 target/ppc/power8-pmu.c          | 15 +++++++++++----
 target/ppc/power8-pmu.h          |  4 ++--
 target/ppc/spr_common.h          |  1 +
 target/ppc/translate.c           |  6 ++++++
 10 files changed, 50 insertions(+), 9 deletions(-)

Comments

Nicholas Piggin Sept. 15, 2023, 12:39 a.m. UTC | #1
On Wed Sep 13, 2023 at 6:23 AM AEST, Glenn Miles wrote:
> This commit is preparatory to the addition of Branch History
> Rolling Buffer (BHRB) functionality, which is being provided
> today starting with the P8 processor.
>
> BHRB uses several SPR register fields to control whether or not
> a branch instruction's address (and sometimes target address)
> should be recorded.  Checking each of these fields with each
> branch instruction using jitted code would lead to a significant
> decrease in performance.
>
> Therefore, it was decided that BHRB configuration bits that are
> not expected to change frequently should have their state stored in
> hflags so that the amount of checking done by jitted code can
> be reduced.
>
> This commit contains the changes for storing the state of the
> following register fields as hflags:
>
> 	MMCR0[FCP] - Determines if BHRB recording is frozen in the
>                      problem state
>
> 	MMCR0[FCPC] - A modifier for MMCR0[FCP]
>
> 	MMCRA[BHRBRD] - Disables all BHRB recording for a thread
>
> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
> ---
>  target/ppc/cpu.h                 |  9 +++++++++
>  target/ppc/cpu_init.c            |  4 ++--
>  target/ppc/helper.h              |  1 +
>  target/ppc/helper_regs.c         | 12 ++++++++++++
>  target/ppc/machine.c             |  2 +-
>  target/ppc/power8-pmu-regs.c.inc |  5 +++++
>  target/ppc/power8-pmu.c          | 15 +++++++++++----
>  target/ppc/power8-pmu.h          |  4 ++--
>  target/ppc/spr_common.h          |  1 +
>  target/ppc/translate.c           |  6 ++++++
>  10 files changed, 50 insertions(+), 9 deletions(-)
>
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index 25fac9577a..20ae1466a5 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -439,6 +439,9 @@ FIELD(MSR, LE, MSR_LE, 1)
>  #define MMCR0_FC56   PPC_BIT(59)         /* PMC Freeze Counters 5-6 bit */
>  #define MMCR0_PMC1CE PPC_BIT(48)         /* MMCR0 PMC1 Condition Enabled */
>  #define MMCR0_PMCjCE PPC_BIT(49)         /* MMCR0 PMCj Condition Enabled */
> +#define MMCR0_BHRBA  PPC_BIT_NR(42)      /* BHRB Available */

It's confusing to use NR for this. Either call it MMCR0_BHRBA_NR or have
the facility check in patch 3 take the bit value. I'd move it to patch 3
too.

> +#define MMCR0_FCP    PPC_BIT(34)         /* Freeze Counters/BHRB if PR=1 */
> +#define MMCR0_FCPC   PPC_BIT(51)         /* Condition for FCP bit */
>  /* MMCR0 userspace r/w mask */
>  #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
>  /* MMCR2 userspace r/w mask */
> @@ -451,6 +454,9 @@ FIELD(MSR, LE, MSR_LE, 1)
>  #define MMCR2_UREG_MASK (MMCR2_FC1P0 | MMCR2_FC2P0 | MMCR2_FC3P0 | \
>                           MMCR2_FC4P0 | MMCR2_FC5P0 | MMCR2_FC6P0)
>  
> +#define MMCRA_BHRBRD    PPC_BIT(26)            /* BHRB Recording Disable */
> +
> +
>  #define MMCR1_EVT_SIZE 8
>  /* extract64() does a right shift before extracting */
>  #define MMCR1_PMC1SEL_START 32
> @@ -703,6 +709,9 @@ enum {
>      HFLAGS_PMCJCE = 17, /* MMCR0 PMCjCE bit */
>      HFLAGS_PMC_OTHER = 18, /* PMC other than PMC5-6 is enabled */
>      HFLAGS_INSN_CNT = 19, /* PMU instruction count enabled */
> +    HFLAGS_FCPC = 20,   /* MMCR0 FCPC bit */
> +    HFLAGS_FCP = 21,    /* MMCR0 FCP bit */
> +    HFLAGS_BHRBRD = 22, /* MMCRA BHRBRD bit */
>      HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
>      HFLAGS_VR = 25,  /* MSR_VR if cpu has VRE */

hflags are an interesting tradeoff. You can specialise some code but
at the cost of duplicating your jit footprint, which is often the
most costly thing. The ideal hflag is one where code is not shared
between flag set/clear like PR and HV. Rarely used features is another
good one, that BHRB falls into.

But, we do want flags that carry stronger or more direct semantics
wrt code generation because you want to avoid redundant hflags values
that result in the same code generation. I might have missed something
but AFAIKS BHRB_ENABLED could be a combination of this logic (from
later patch):

+    /* ISA 3.1 adds the PMCRA[BRHBRD] and problem state checks */
+    if ((ctx->insns_flags2 & PPC2_ISA310) && (ctx->mmcra_bhrbrd || !ctx->pr)) {
+        return;
+    }
+
+    /* Check for BHRB "frozen" conditions */
+    if (ctx->mmcr0_fcpc) {
+        if (ctx->mmcr0_fcp) {
+            if ((ctx->hv) && (ctx->pr)) {
+                return;
+            }
+        } else if (!(ctx->hv) && (ctx->pr)) {
+            return;
+        }
+    } else if ((ctx->mmcr0_fcp) && (ctx->pr)) {
+        return;
+    }

Otherwise the patch looks good to me.

Thanks,
Nick
Glenn Miles Sept. 19, 2023, 9:19 p.m. UTC | #2
On 2023-09-14 19:39, Nicholas Piggin wrote:
> On Wed Sep 13, 2023 at 6:23 AM AEST, Glenn Miles wrote:
>> This commit is preparatory to the addition of Branch History
>> Rolling Buffer (BHRB) functionality, which is being provided
>> today starting with the P8 processor.
>> 
>> BHRB uses several SPR register fields to control whether or not
>> a branch instruction's address (and sometimes target address)
>> should be recorded.  Checking each of these fields with each
>> branch instruction using jitted code would lead to a significant
>> decrease in performance.
>> 
>> Therefore, it was decided that BHRB configuration bits that are
>> not expected to change frequently should have their state stored in
>> hflags so that the amount of checking done by jitted code can
>> be reduced.
>> 
>> This commit contains the changes for storing the state of the
>> following register fields as hflags:
>> 
>> 	MMCR0[FCP] - Determines if BHRB recording is frozen in the
>>                      problem state
>> 
>> 	MMCR0[FCPC] - A modifier for MMCR0[FCP]
>> 
>> 	MMCRA[BHRBRD] - Disables all BHRB recording for a thread
>> 
>> Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
>> ---
>>  target/ppc/cpu.h                 |  9 +++++++++
>>  target/ppc/cpu_init.c            |  4 ++--
>>  target/ppc/helper.h              |  1 +
>>  target/ppc/helper_regs.c         | 12 ++++++++++++
>>  target/ppc/machine.c             |  2 +-
>>  target/ppc/power8-pmu-regs.c.inc |  5 +++++
>>  target/ppc/power8-pmu.c          | 15 +++++++++++----
>>  target/ppc/power8-pmu.h          |  4 ++--
>>  target/ppc/spr_common.h          |  1 +
>>  target/ppc/translate.c           |  6 ++++++
>>  10 files changed, 50 insertions(+), 9 deletions(-)
>> 
>> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
>> index 25fac9577a..20ae1466a5 100644
>> --- a/target/ppc/cpu.h
>> +++ b/target/ppc/cpu.h
>> @@ -439,6 +439,9 @@ FIELD(MSR, LE, MSR_LE, 1)
>>  #define MMCR0_FC56   PPC_BIT(59)         /* PMC Freeze Counters 5-6 
>> bit */
>>  #define MMCR0_PMC1CE PPC_BIT(48)         /* MMCR0 PMC1 Condition 
>> Enabled */
>>  #define MMCR0_PMCjCE PPC_BIT(49)         /* MMCR0 PMCj Condition 
>> Enabled */
>> +#define MMCR0_BHRBA  PPC_BIT_NR(42)      /* BHRB Available */
> 
> It's confusing to use NR for this. Either call it MMCR0_BHRBA_NR or 
> have
> the facility check in patch 3 take the bit value. I'd move it to patch 
> 3
> too.
> 

Ok, adding NR suffix.

>> +#define MMCR0_FCP    PPC_BIT(34)         /* Freeze Counters/BHRB if 
>> PR=1 */
>> +#define MMCR0_FCPC   PPC_BIT(51)         /* Condition for FCP bit */
>>  /* MMCR0 userspace r/w mask */
>>  #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
>>  /* MMCR2 userspace r/w mask */
>> @@ -451,6 +454,9 @@ FIELD(MSR, LE, MSR_LE, 1)
>>  #define MMCR2_UREG_MASK (MMCR2_FC1P0 | MMCR2_FC2P0 | MMCR2_FC3P0 | \
>>                           MMCR2_FC4P0 | MMCR2_FC5P0 | MMCR2_FC6P0)
>> 
>> +#define MMCRA_BHRBRD    PPC_BIT(26)            /* BHRB Recording 
>> Disable */
>> +
>> +
>>  #define MMCR1_EVT_SIZE 8
>>  /* extract64() does a right shift before extracting */
>>  #define MMCR1_PMC1SEL_START 32
>> @@ -703,6 +709,9 @@ enum {
>>      HFLAGS_PMCJCE = 17, /* MMCR0 PMCjCE bit */
>>      HFLAGS_PMC_OTHER = 18, /* PMC other than PMC5-6 is enabled */
>>      HFLAGS_INSN_CNT = 19, /* PMU instruction count enabled */
>> +    HFLAGS_FCPC = 20,   /* MMCR0 FCPC bit */
>> +    HFLAGS_FCP = 21,    /* MMCR0 FCP bit */
>> +    HFLAGS_BHRBRD = 22, /* MMCRA BHRBRD bit */
>>      HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
>>      HFLAGS_VR = 25,  /* MSR_VR if cpu has VRE */
> 
> hflags are an interesting tradeoff. You can specialise some code but
> at the cost of duplicating your jit footprint, which is often the
> most costly thing. The ideal hflag is one where code is not shared
> between flag set/clear like PR and HV. Rarely used features is another
> good one, that BHRB falls into.
> 
> But, we do want flags that carry stronger or more direct semantics
> wrt code generation because you want to avoid redundant hflags values
> that result in the same code generation. I might have missed something
> but AFAIKS BHRB_ENABLED could be a combination of this logic (from
> later patch):
> 
> +    /* ISA 3.1 adds the PMCRA[BRHBRD] and problem state checks */
> +    if ((ctx->insns_flags2 & PPC2_ISA310) && (ctx->mmcra_bhrbrd || 
> !ctx->pr)) {
> +        return;
> +    }
> +
> +    /* Check for BHRB "frozen" conditions */
> +    if (ctx->mmcr0_fcpc) {
> +        if (ctx->mmcr0_fcp) {
> +            if ((ctx->hv) && (ctx->pr)) {
> +                return;
> +            }
> +        } else if (!(ctx->hv) && (ctx->pr)) {
> +            return;
> +        }
> +    } else if ((ctx->mmcr0_fcp) && (ctx->pr)) {
> +        return;
> +    }
> 

Ok, Combining above logic into a single hflag.

> Otherwise the patch looks good to me.
> 
> Thanks,
> Nick
diff mbox series

Patch

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 25fac9577a..20ae1466a5 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -439,6 +439,9 @@  FIELD(MSR, LE, MSR_LE, 1)
 #define MMCR0_FC56   PPC_BIT(59)         /* PMC Freeze Counters 5-6 bit */
 #define MMCR0_PMC1CE PPC_BIT(48)         /* MMCR0 PMC1 Condition Enabled */
 #define MMCR0_PMCjCE PPC_BIT(49)         /* MMCR0 PMCj Condition Enabled */
+#define MMCR0_BHRBA  PPC_BIT_NR(42)      /* BHRB Available */
+#define MMCR0_FCP    PPC_BIT(34)         /* Freeze Counters/BHRB if PR=1 */
+#define MMCR0_FCPC   PPC_BIT(51)         /* Condition for FCP bit */
 /* MMCR0 userspace r/w mask */
 #define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
 /* MMCR2 userspace r/w mask */
@@ -451,6 +454,9 @@  FIELD(MSR, LE, MSR_LE, 1)
 #define MMCR2_UREG_MASK (MMCR2_FC1P0 | MMCR2_FC2P0 | MMCR2_FC3P0 | \
                          MMCR2_FC4P0 | MMCR2_FC5P0 | MMCR2_FC6P0)
 
+#define MMCRA_BHRBRD    PPC_BIT(26)            /* BHRB Recording Disable */
+
+
 #define MMCR1_EVT_SIZE 8
 /* extract64() does a right shift before extracting */
 #define MMCR1_PMC1SEL_START 32
@@ -703,6 +709,9 @@  enum {
     HFLAGS_PMCJCE = 17, /* MMCR0 PMCjCE bit */
     HFLAGS_PMC_OTHER = 18, /* PMC other than PMC5-6 is enabled */
     HFLAGS_INSN_CNT = 19, /* PMU instruction count enabled */
+    HFLAGS_FCPC = 20,   /* MMCR0 FCPC bit */
+    HFLAGS_FCP = 21,    /* MMCR0 FCP bit */
+    HFLAGS_BHRBRD = 22, /* MMCRA BHRBRD bit */
     HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */
     HFLAGS_VR = 25,  /* MSR_VR if cpu has VRE */
 
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 02b7aad9b0..568f9c3b88 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -5152,7 +5152,7 @@  static void register_book3s_pmu_sup_sprs(CPUPPCState *env)
                      KVM_REG_PPC_MMCR1, 0x00000000);
     spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
                      SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
+                     &spr_read_generic, &spr_write_MMCRA,
                      KVM_REG_PPC_MMCRA, 0x00000000);
     spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
                      SPR_NOACCESS, SPR_NOACCESS,
@@ -7152,7 +7152,7 @@  static void ppc_cpu_reset_hold(Object *obj)
         if (env->mmu_model != POWERPC_MMU_REAL) {
             ppc_tlb_invalidate_all(env);
         }
-        pmu_mmcr01_updated(env);
+        pmu_mmcr01a_updated(env);
     }
 
     /* clean any pending stop state */
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index abec6fe341..1a3d9a7e57 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -27,6 +27,7 @@  DEF_HELPER_2(store_lpcr, void, env, tl)
 DEF_HELPER_2(store_pcr, void, env, tl)
 DEF_HELPER_2(store_mmcr0, void, env, tl)
 DEF_HELPER_2(store_mmcr1, void, env, tl)
+DEF_HELPER_2(store_mmcrA, void, env, tl)
 DEF_HELPER_3(store_pmc, void, env, i32, i64)
 DEF_HELPER_2(read_pmc, tl, env, i32)
 DEF_HELPER_2(insns_inc, void, env, i32)
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index f380342d4d..4ff054063d 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -61,6 +61,15 @@  static uint32_t hreg_compute_pmu_hflags_value(CPUPPCState *env)
     if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE) {
         hflags |= 1 << HFLAGS_PMCJCE;
     }
+    if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCP) {
+        hflags |= 1 << HFLAGS_FCP;
+    }
+    if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCPC) {
+        hflags |= 1 << HFLAGS_FCPC;
+    }
+    if (env->spr[SPR_POWER_MMCRA] & MMCRA_BHRBRD) {
+        hflags |= 1 << HFLAGS_BHRBRD;
+    }
 
 #ifndef CONFIG_USER_ONLY
     if (env->pmc_ins_cnt) {
@@ -85,6 +94,9 @@  static uint32_t hreg_compute_pmu_hflags_mask(CPUPPCState *env)
     hflags_mask |= 1 << HFLAGS_PMCJCE;
     hflags_mask |= 1 << HFLAGS_INSN_CNT;
     hflags_mask |= 1 << HFLAGS_PMC_OTHER;
+    hflags_mask |= 1 << HFLAGS_FCP;
+    hflags_mask |= 1 << HFLAGS_FCPC;
+    hflags_mask |= 1 << HFLAGS_BHRBRD;
 #endif
     return hflags_mask;
 }
diff --git a/target/ppc/machine.c b/target/ppc/machine.c
index 1270a1f7fc..b195fb4dc8 100644
--- a/target/ppc/machine.c
+++ b/target/ppc/machine.c
@@ -313,7 +313,7 @@  static int cpu_post_load(void *opaque, int version_id)
     post_load_update_msr(env);
 
     if (tcg_enabled()) {
-        pmu_mmcr01_updated(env);
+        pmu_mmcr01a_updated(env);
     }
 
     return 0;
diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc
index c82feedaff..cab488918a 100644
--- a/target/ppc/power8-pmu-regs.c.inc
+++ b/target/ppc/power8-pmu-regs.c.inc
@@ -175,6 +175,11 @@  void spr_write_MMCR2_ureg(DisasContext *ctx, int sprn, int gprn)
     gen_store_spr(SPR_POWER_MMCR2, masked_gprn);
 }
 
+void spr_write_MMCRA(DisasContext *ctx, int sprn, int gprn)
+{
+    gen_helper_store_mmcrA(cpu_env, cpu_gpr[gprn]);
+}
+
 void spr_read_PMC(DisasContext *ctx, int gprn, int sprn)
 {
     TCGv_i32 t_sprn = tcg_constant_i32(sprn);
diff --git a/target/ppc/power8-pmu.c b/target/ppc/power8-pmu.c
index cbc5889d91..6f5d4e1256 100644
--- a/target/ppc/power8-pmu.c
+++ b/target/ppc/power8-pmu.c
@@ -82,7 +82,7 @@  static void pmu_update_summaries(CPUPPCState *env)
     env->pmc_cyc_cnt = cyc_cnt;
 }
 
-void pmu_mmcr01_updated(CPUPPCState *env)
+void pmu_mmcr01a_updated(CPUPPCState *env)
 {
     PowerPCCPU *cpu = env_archcpu(env);
 
@@ -260,7 +260,7 @@  void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
 
     env->spr[SPR_POWER_MMCR0] = value;
 
-    pmu_mmcr01_updated(env);
+    pmu_mmcr01a_updated(env);
 
     /* Update cycle overflow timers with the current MMCR0 state */
     pmu_update_overflow_timers(env);
@@ -272,7 +272,14 @@  void helper_store_mmcr1(CPUPPCState *env, uint64_t value)
 
     env->spr[SPR_POWER_MMCR1] = value;
 
-    pmu_mmcr01_updated(env);
+    pmu_mmcr01a_updated(env);
+}
+
+void helper_store_mmcrA(CPUPPCState *env, uint64_t value)
+{
+    env->spr[SPR_POWER_MMCRA] = value;
+
+    pmu_mmcr01a_updated(env);
 }
 
 target_ulong helper_read_pmc(CPUPPCState *env, uint32_t sprn)
@@ -301,7 +308,7 @@  static void perfm_alert(PowerPCCPU *cpu)
         env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;
 
         /* Changing MMCR0_FC requires summaries and hflags update */
-        pmu_mmcr01_updated(env);
+        pmu_mmcr01a_updated(env);
 
         /*
          * Delete all pending timers if we need to freeze
diff --git a/target/ppc/power8-pmu.h b/target/ppc/power8-pmu.h
index 775e640053..87fa8c9334 100644
--- a/target/ppc/power8-pmu.h
+++ b/target/ppc/power8-pmu.h
@@ -18,10 +18,10 @@ 
 #define PMC_COUNTER_NEGATIVE_VAL 0x80000000UL
 
 void cpu_ppc_pmu_init(CPUPPCState *env);
-void pmu_mmcr01_updated(CPUPPCState *env);
+void pmu_mmcr01a_updated(CPUPPCState *env);
 #else
 static inline void cpu_ppc_pmu_init(CPUPPCState *env) { }
-static inline void pmu_mmcr01_updated(CPUPPCState *env) { }
+static inline void pmu_mmcr01a_updated(CPUPPCState *env) { }
 #endif
 
 #endif
diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h
index 5995070eaf..3c499c1ebd 100644
--- a/target/ppc/spr_common.h
+++ b/target/ppc/spr_common.h
@@ -85,6 +85,7 @@  void spr_write_generic32(DisasContext *ctx, int sprn, int gprn);
 void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn);
 void spr_write_MMCR0(DisasContext *ctx, int sprn, int gprn);
 void spr_write_MMCR1(DisasContext *ctx, int sprn, int gprn);
+void spr_write_MMCRA(DisasContext *ctx, int sprn, int gprn);
 void spr_write_PMC(DisasContext *ctx, int sprn, int gprn);
 void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn);
 void spr_read_xer(DisasContext *ctx, int gprn, int sprn);
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 7111b34030..d93fbd4574 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -190,6 +190,9 @@  struct DisasContext {
     bool mmcr0_pmcjce;
     bool pmc_other;
     bool pmu_insn_cnt;
+    bool mmcr0_fcpc;
+    bool mmcr0_fcp;
+    bool mmcra_bhrbrd;
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
     uint32_t flags;
@@ -7326,6 +7329,9 @@  static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->mmcr0_pmcjce = (hflags >> HFLAGS_PMCJCE) & 1;
     ctx->pmc_other = (hflags >> HFLAGS_PMC_OTHER) & 1;
     ctx->pmu_insn_cnt = (hflags >> HFLAGS_INSN_CNT) & 1;
+    ctx->mmcr0_fcpc = (hflags >> HFLAGS_FCPC) & 1;
+    ctx->mmcr0_fcp = (hflags >> HFLAGS_FCP) & 1;
+    ctx->mmcra_bhrbrd = (hflags >> HFLAGS_BHRBRD) & 1;
 
     ctx->singlestep_enabled = 0;
     if ((hflags >> HFLAGS_SE) & 1) {