Skip to content

Commit

Permalink
target/arm: Move mode specific TB flags to tb->cs_base
Browse files Browse the repository at this point in the history
Now that we have all of the proper macros defined, expanding
the CPUARMTBFlags structure and populating the two TB fields
is relatively simple.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210419202257.161730-7-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
rth7680 authored and pm215 committed Apr 30, 2021
1 parent 3902bfc commit a378206
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 26 deletions.
49 changes: 28 additions & 21 deletions target/arm/cpu.h
Expand Up @@ -228,6 +228,7 @@ typedef struct ARMPACKey {
/* See the commentary above the TBFLAG field definitions. */
typedef struct CPUARMTBFlags {
uint32_t flags;
target_ulong flags2;
} CPUARMTBFlags;

typedef struct CPUARMState {
Expand Down Expand Up @@ -3381,20 +3382,26 @@ typedef ARMCPU ArchCPU;
#include "exec/cpu-all.h"

/*
* Bit usage in the TB flags field: bit 31 indicates whether we are
* in 32 or 64 bit mode. The meaning of the other bits depends on that.
* We put flags which are shared between 32 and 64 bit mode at the top
* of the word, and flags which apply to only one mode at the bottom.
* We have more than 32-bits worth of state per TB, so we split the data
* between tb->flags and tb->cs_base, which is otherwise unused for ARM.
* We collect these two parts in CPUARMTBFlags where they are named
* flags and flags2 respectively.
*
* 31 20 18 14 9 0
* +--------------+-----+-----+----------+--------------+
* | | | TBFLAG_A32 | |
* | | +-----+----------+ TBFLAG_AM32 |
* | TBFLAG_ANY | |TBFLAG_M32| |
* | +-----------+----------+--------------|
* | | TBFLAG_A64 |
* +--------------+-------------------------------------+
* 31 20 0
* The flags that are shared between all execution modes, TBFLAG_ANY,
* are stored in flags. The flags that are specific to a given mode
* are stores in flags2. Since cs_base is sized on the configured
* address size, flags2 always has 64-bits for A64, and a minimum of
* 32-bits for A32 and M32.
*
* The bits for 32-bit A-profile and M-profile partially overlap:
*
* 18 9 0
* +----------------+--------------+
* | TBFLAG_A32 | |
* +-----+----------+ TBFLAG_AM32 |
* | |TBFLAG_M32| |
* +-----+----------+--------------+
* 14 9 0
*
* Unless otherwise noted, these bits are cached in env->hflags.
*/
Expand Down Expand Up @@ -3472,19 +3479,19 @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A64, WHICH, VAL))
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A32, WHICH, VAL))
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_M32, WHICH, VAL))
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
(DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_AM32, WHICH, VAL))

#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A64, WHICH)
#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A32, WHICH)
#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)

/**
* cpu_mmu_index:
Expand Down
10 changes: 6 additions & 4 deletions target/arm/helper.c
Expand Up @@ -13256,9 +13256,11 @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
CPUARMTBFlags c = env->hflags;
CPUARMTBFlags r = rebuild_hflags_internal(env);

if (unlikely(c.flags != r.flags)) {
fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
c.flags, r.flags);
if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
fprintf(stderr, "TCG hflags mismatch "
"(current:(0x%08x,0x" TARGET_FMT_lx ")"
" rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
c.flags, c.flags2, r.flags, r.flags2);
abort();
}
#endif
Expand All @@ -13269,7 +13271,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
{
CPUARMTBFlags flags;

*cs_base = 0;
assert_hflags_rebuild_correctly(env);
flags = env->hflags;

Expand Down Expand Up @@ -13338,6 +13339,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
}

*pflags = flags.flags;
*cs_base = flags.flags2;
}

#ifdef TARGET_AARCH64
Expand Down
2 changes: 1 addition & 1 deletion target/arm/translate.h
Expand Up @@ -402,7 +402,7 @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
*/
static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
{
return (CPUARMTBFlags){ tb->flags };
return (CPUARMTBFlags){ tb->flags, tb->cs_base };
}

/*
Expand Down

0 comments on commit a378206

Please sign in to comment.