diff mbox series

[v1,11/11] target/arm: Enable BFloat16 extensions

Message ID 20210416235928.1631788-12-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Implement BFloat16 | expand

Commit Message

Richard Henderson April 16, 2021, 11:59 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 target/arm/cpu64.c   | 3 +++
 target/arm/cpu_tcg.c | 1 +
 2 files changed, 4 insertions(+)

-- 
2.25.1

Comments

Peter Maydell May 18, 2021, 12:47 p.m. UTC | #1
On Sat, 17 Apr 2021 at 01:05, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  target/arm/cpu64.c   | 3 +++

>  target/arm/cpu_tcg.c | 1 +

>  2 files changed, 4 insertions(+)

>

> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c

> index 379f90fab8..db4f48edcf 100644

> --- a/target/arm/cpu64.c

> +++ b/target/arm/cpu64.c

> @@ -660,6 +660,7 @@ static void aarch64_max_initfn(Object *obj)

>          t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);

>          t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);

>          t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);

> +        t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);

>          t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);

>          t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */

>          t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);

> @@ -707,6 +708,7 @@ static void aarch64_max_initfn(Object *obj)

>          t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);

>          t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2);  /* PMULL */

>          t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);

> +        t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);

>          t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);

>          t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);

>          t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);

> @@ -730,6 +732,7 @@ static void aarch64_max_initfn(Object *obj)

>          u = FIELD_DP32(u, ID_ISAR6, FHM, 1);

>          u = FIELD_DP32(u, ID_ISAR6, SB, 1);

>          u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);

> +        u = FIELD_DP32(u, ID_ISAR6, BF16, 1);

>          u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);

>          cpu->isar.id_isar6 = u;

>

> diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c

> index 046e476f65..b2463cf109 100644

> --- a/target/arm/cpu_tcg.c

> +++ b/target/arm/cpu_tcg.c

> @@ -968,6 +968,7 @@ static void arm_max_initfn(Object *obj)

>          t = FIELD_DP32(t, ID_ISAR6, FHM, 1);

>          t = FIELD_DP32(t, ID_ISAR6, SB, 1);

>          t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);

> +        t = FIELD_DP32(t, ID_ISAR6, BF16, 1);

>          cpu->isar.id_isar6 = t;

>

>          t = cpu->isar.mvfr1;


Same query as with SVE: do we need to clear these in the "!has_vfp"
and "!has_neon" handling code in arm_cpu_realizefn() ?

thanks
-- PMM
Richard Henderson May 18, 2021, 2:47 p.m. UTC | #2
On 5/18/21 7:47 AM, Peter Maydell wrote:
>> diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c

>> index 046e476f65..b2463cf109 100644

>> --- a/target/arm/cpu_tcg.c

>> +++ b/target/arm/cpu_tcg.c

>> @@ -968,6 +968,7 @@ static void arm_max_initfn(Object *obj)

>>           t = FIELD_DP32(t, ID_ISAR6, FHM, 1);

>>           t = FIELD_DP32(t, ID_ISAR6, SB, 1);

>>           t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);

>> +        t = FIELD_DP32(t, ID_ISAR6, BF16, 1);

>>           cpu->isar.id_isar6 = t;

>>

>>           t = cpu->isar.mvfr1;

> 

> Same query as with SVE: do we need to clear these in the "!has_vfp"

> and "!has_neon" handling code in arm_cpu_realizefn() ?


I *think* we want to clear ID_ISAR6 only when !has_vfp && !has_neon, as 
FEAT_AA32BF16 should still be usable to the other one.  Which also means adding 
the NEON/VFP check you suggested.


r~
Richard Henderson May 25, 2021, 4:57 p.m. UTC | #3
On 5/18/21 7:47 AM, Richard Henderson wrote:
> On 5/18/21 7:47 AM, Peter Maydell wrote:

>>> diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c

>>> index 046e476f65..b2463cf109 100644

>>> --- a/target/arm/cpu_tcg.c

>>> +++ b/target/arm/cpu_tcg.c

>>> @@ -968,6 +968,7 @@ static void arm_max_initfn(Object *obj)

>>>           t = FIELD_DP32(t, ID_ISAR6, FHM, 1);

>>>           t = FIELD_DP32(t, ID_ISAR6, SB, 1);

>>>           t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);

>>> +        t = FIELD_DP32(t, ID_ISAR6, BF16, 1);

>>>           cpu->isar.id_isar6 = t;

>>>

>>>           t = cpu->isar.mvfr1;

>>

>> Same query as with SVE: do we need to clear these in the "!has_vfp"

>> and "!has_neon" handling code in arm_cpu_realizefn() ?

> 

> I *think* we want to clear ID_ISAR6 only when !has_vfp && !has_neon, as 

> FEAT_AA32BF16 should still be usable to the other one.  Which also means adding 

> the NEON/VFP check you suggested.


Alternately, we can clear BF16 when either !vfp or !neon, and then we don't 
have to add the extra checks.

Unless we're presented with a real cpu that has vfp but not neon, and does have 
bf16, this seems like a head-scratcher corner case.  Just so long as we don't 
do something actively against the rules I guess we're ok.


r~
diff mbox series

Patch

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 379f90fab8..db4f48edcf 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -660,6 +660,7 @@  static void aarch64_max_initfn(Object *obj)
         t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
         t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
         t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
+        t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
         t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
         t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
         t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
@@ -707,6 +708,7 @@  static void aarch64_max_initfn(Object *obj)
         t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
         t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2);  /* PMULL */
         t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
+        t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
         t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
         t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
         t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
@@ -730,6 +732,7 @@  static void aarch64_max_initfn(Object *obj)
         u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
         u = FIELD_DP32(u, ID_ISAR6, SB, 1);
         u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
+        u = FIELD_DP32(u, ID_ISAR6, BF16, 1);
         u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);
         cpu->isar.id_isar6 = u;
 
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 046e476f65..b2463cf109 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -968,6 +968,7 @@  static void arm_max_initfn(Object *obj)
         t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
         t = FIELD_DP32(t, ID_ISAR6, SB, 1);
         t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
+        t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
         cpu->isar.id_isar6 = t;
 
         t = cpu->isar.mvfr1;