diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2023-09-15 15:37:00 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2023-09-21 16:07:13 +0100 |
commit | 3039b090f2058949edf6a7f1c8e793bc309fa6de (patch) | |
tree | f14ee1a36a3267e5d8c66c0f2b6178a2db861506 | |
parent | 5f7b71fb99dc98831d9ad077fe1a58a4b119e952 (diff) | |
download | qemu-3039b090f2058949edf6a7f1c8e793bc309fa6de.zip qemu-3039b090f2058949edf6a7f1c8e793bc309fa6de.tar.gz qemu-3039b090f2058949edf6a7f1c8e793bc309fa6de.tar.bz2 |
target/arm: Implement FEAT_HBC
FEAT_HBC (Hinted conditional branches) provides a new instruction
BC.cond, which behaves exactly like the existing B.cond except
that it provides a hint to the branch predictor about the
likely behaviour of the branch.
Since QEMU does not implement branch prediction, we can treat
this identically to B.cond.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r-- | docs/system/arm/emulation.rst | 1 | ||||
-rw-r--r-- | linux-user/elfload.c | 1 | ||||
-rw-r--r-- | target/arm/cpu.h | 5 | ||||
-rw-r--r-- | target/arm/tcg/a64.decode | 3 | ||||
-rw-r--r-- | target/arm/tcg/cpu64.c | 4 | ||||
-rw-r--r-- | target/arm/tcg/translate-a64.c | 4 |
6 files changed, 17 insertions, 1 deletions
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst index 3df936f..1fb6a2e 100644 --- a/docs/system/arm/emulation.rst +++ b/docs/system/arm/emulation.rst @@ -42,6 +42,7 @@ the following architecture extensions: - FEAT_FlagM2 (Enhancements to flag manipulation instructions) - FEAT_GTG (Guest translation granule size) - FEAT_HAFDBS (Hardware management of the access flag and dirty bit state) +- FEAT_HBC (Hinted conditional branches) - FEAT_HCX (Support for the HCRX_EL2 register) - FEAT_HPDS (Hierarchical permission disables) - FEAT_HPDS2 (Translation table page-based hardware attributes) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index bbb4f08..203a2b7 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -815,6 +815,7 @@ uint32_t get_elf_hwcap2(void) GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64); GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64); GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64); + GET_FEATURE_ID(aa64_hbc, ARM_HWCAP2_A64_HBC); return hwcaps; } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7ba2402..bc7a69a 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -4088,6 +4088,11 @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0; } +static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0; +} + static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id) { return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1; diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode index ef64a3f..7111317 100644 --- a/target/arm/tcg/a64.decode +++ b/target/arm/tcg/a64.decode @@ -126,7 +126,8 @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19 TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19 -B_cond 0101010 0 ................... 0 cond:4 imm=%imm19 +# B.cond and BC.cond +B_cond 0101010 0 ................... c:1 cond:4 imm=%imm19 BR 1101011 0000 11111 000000 rn:5 00000 &r BLR 1101011 0001 11111 000000 rn:5 00000 &r diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c index 7264ab5..57abaea 100644 --- a/target/arm/tcg/cpu64.c +++ b/target/arm/tcg/cpu64.c @@ -1027,6 +1027,10 @@ void aarch64_max_tcg_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */ cpu->isar.id_aa64isar1 = t; + t = cpu->isar.id_aa64isar2; + t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */ + cpu->isar.id_aa64isar2 = t; + t = cpu->isar.id_aa64pfr0; t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */ diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 1b6fbb6..1dd86ed 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -1453,6 +1453,10 @@ static bool trans_TBZ(DisasContext *s, arg_tbz *a) static bool trans_B_cond(DisasContext *s, arg_B_cond *a) { + /* BC.cond is only present with FEAT_HBC */ + if (a->c && !dc_isar_feature(aa64_hbc, s)) { + return false; + } reset_btype(s); if (a->cond < 0x0e) { /* genuinely conditional branches */ |