aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2019-03-01 12:04:53 -0800
committerPeter Maydell <peter.maydell@linaro.org>2019-03-05 15:55:07 +0000
commit9888bd1e20425dfe4dcca5dcd1ca2fac8e90ad19 (patch)
treef0cdc842e6f75974b15cb3b7cd33d0e10332970d
parent64e40755cd41fbe8cd266cf387e42ddc57a449ef (diff)
target/arm: Implement ARMv8.0-SB
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190301200501.16533-3-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--linux-user/elfload.c1
-rw-r--r--target/arm/cpu.c1
-rw-r--r--target/arm/cpu.h10
-rw-r--r--target/arm/cpu64.c2
-rw-r--r--target/arm/translate-a64.c14
-rw-r--r--target/arm/translate.c22
6 files changed, 50 insertions, 0 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index b9f7cbbdc1..6cfebe1446 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -604,6 +604,7 @@ static uint32_t get_elf_hwcap(void)
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
+ GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
#undef GET_FEATURE_ID
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 54b61f917b..ef069c268d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2021,6 +2021,7 @@ static void arm_max_initfn(Object *obj)
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
cpu->isar.id_isar6 = t;
t = cpu->id_mmfr4;
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 67b06bfad0..361e51143c 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3307,6 +3307,11 @@ static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
}
+static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
+{
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
+}
+
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
{
/*
@@ -3445,6 +3450,11 @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
}
+static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
+{
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
+}
+
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
{
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 1b0c427277..6788c0f6ff 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -318,6 +318,7 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
cpu->isar.id_aa64isar1 = t;
t = cpu->isar.id_aa64pfr0;
@@ -349,6 +350,7 @@ static void aarch64_max_initfn(Object *obj)
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
+ u = FIELD_DP32(u, ID_ISAR6, SB, 1);
cpu->isar.id_isar6 = u;
/*
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d3c8eaf089..4aa5a307e4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1637,7 +1637,21 @@ static void handle_sync(DisasContext *s, uint32_t insn,
reset_btype(s);
gen_goto_tb(s, 0, s->pc);
return;
+
+ case 7: /* SB */
+ if (crm != 0 || !dc_isar_feature(aa64_sb, s)) {
+ goto do_unallocated;
+ }
+ /*
+ * TODO: There is no speculation barrier opcode for TCG;
+ * MB and end the TB instead.
+ */
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+ gen_goto_tb(s, 0, s->pc);
+ return;
+
default:
+ do_unallocated:
unallocated_encoding(s);
return;
}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index ad879e3480..9f71206f85 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -9282,6 +9282,17 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
*/
gen_goto_tb(s, 0, s->pc & ~1);
return;
+ case 7: /* sb */
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
+ goto illegal_op;
+ }
+ /*
+ * TODO: There is no speculation barrier opcode
+ * for TCG; MB and end the TB instead.
+ */
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+ gen_goto_tb(s, 0, s->pc & ~1);
+ return;
default:
goto illegal_op;
}
@@ -11900,6 +11911,17 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
*/
gen_goto_tb(s, 0, s->pc & ~1);
break;
+ case 7: /* sb */
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
+ goto illegal_op;
+ }
+ /*
+ * TODO: There is no speculation barrier opcode
+ * for TCG; MB and end the TB instead.
+ */
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
+ gen_goto_tb(s, 0, s->pc & ~1);
+ break;
default:
goto illegal_op;
}