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(+)

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;