[PATCH v3 03/16] target/hexagon/cpu: add HVX IEEE FP extension

Matheus Tavares Bernardino posted 16 patches 3 days ago
Maintainers: Brian Cain <brian.cain@oss.qualcomm.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
There is a newer version of this series
[PATCH v3 03/16] target/hexagon/cpu: add HVX IEEE FP extension
Posted by Matheus Tavares Bernardino 3 days ago
This flag will be used to control the HVX IEEE float instructions, which
are only available at some Hexagon cores. When unavailable, the
instruction effectively only set the destination registers to 0.

Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
---
 target/hexagon/cpu.h             |  1 +
 target/hexagon/translate.h       |  1 +
 target/hexagon/attribs_def.h.inc |  3 +++
 target/hexagon/cpu.c             |  1 +
 target/hexagon/translate.c       |  1 +
 target/hexagon/gen_tcg_funcs.py  | 11 ++++++++++
 target/hexagon/hex_common.py     | 35 ++++++++++++++++++++++++++++++++
 7 files changed, 53 insertions(+)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 85afd59277..77822a48b6 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -127,6 +127,7 @@ struct ArchCPU {
     bool lldb_compat;
     target_ulong lldb_stack_adjust;
     bool short_circuit;
+    bool ieee_fp_extension;
 };
 
 #include "cpu_bits.h"
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index b37cb49238..516aab7038 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -70,6 +70,7 @@ typedef struct DisasContext {
     target_ulong branch_dest;
     bool is_tight_loop;
     bool short_circuit;
+    bool ieee_fp_extension;
     bool read_after_write;
     bool has_hvx_overlap;
     TCGv new_value[TOTAL_PER_THREAD_REGS];
diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc
index 9e3a05f882..c85cd5d17c 100644
--- a/target/hexagon/attribs_def.h.inc
+++ b/target/hexagon/attribs_def.h.inc
@@ -173,5 +173,8 @@ DEF_ATTRIB(NOTE_SHIFT_RESOURCE, "Uses the HVX shift resource.", "", "")
 DEF_ATTRIB(RESTRICT_NOSLOT1_STORE, "Packet must not have slot 1 store", "", "")
 DEF_ATTRIB(RESTRICT_LATEPRED, "Predicate can not be used as a .new.", "", "")
 
+/* HVX IEEE FP extension attributes */
+DEF_ATTRIB(HVX_IEEE_FP, "HVX IEEE FP extension instruction", "", "")
+
 /* Keep this as the last attribute: */
 DEF_ATTRIB(ZZ_LASTATTRIB, "Last attribute in the file", "", "")
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index ffd14bb467..8b72a5d3c8 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -54,6 +54,7 @@ static const Property hexagon_cpu_properties[] = {
     DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 0,
                          qdev_prop_uint32, target_ulong),
     DEFINE_PROP_BOOL("short-circuit", HexagonCPU, short_circuit, true),
+    DEFINE_PROP_BOOL("ieee-fp", HexagonCPU, ieee_fp_extension, true),
 };
 
 const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 633401451d..fa8f615a9e 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -988,6 +988,7 @@ static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
     ctx->branch_cond = TCG_COND_NEVER;
     ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
     ctx->short_circuit = hex_cpu->short_circuit;
+    ctx->ieee_fp_extension = hex_cpu->ieee_fp_extension;
 }
 
 static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 87b7f10d7f..b752ec883c 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -22,6 +22,14 @@
 import string
 import hex_common
 
+def gen_disabled_ieee_insn(f, tag, regs):
+    f.write("    if (!ctx->ieee_fp_extension) {\n")
+    for regtype, regid in regs:
+        reg = hex_common.get_register(tag, regtype, regid)
+        if reg.is_hvx_reg() and reg.is_written():
+            reg.gen_zero(f)
+    f.write("        return;\n")
+    f.write("    }\n")
 
 ##
 ## Generate the TCG code to call the helper
@@ -62,6 +70,9 @@ def gen_tcg_func(f, tag, regs, imms):
         i = 1 if immlett.isupper() else 0
         f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
 
+    if "A_HVX_IEEE_FP" in hex_common.attribdict[tag]:
+        gen_disabled_ieee_insn(f, tag, regs)
+
     if hex_common.is_idef_parser_enabled(tag):
         declared = []
         ## Handle registers
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index c0e9f26aeb..32a61505ce 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -723,6 +723,11 @@ def decl_tcg(self, f, tag, regno):
                 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
                 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                    sizeof(MMVector), sizeof(MMVector), 0);
+            """))
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
@@ -789,6 +794,11 @@ def decl_tcg(self, f, tag, regno):
                 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
                 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                    sizeof(MMVector), sizeof(MMVector), 0);
+            """))
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
@@ -821,6 +831,11 @@ def decl_tcg(self, f, tag, regno):
                                  vreg_src_off(ctx, {self.reg_num}),
                                  sizeof(MMVector), sizeof(MMVector));
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                    sizeof(MMVector), sizeof(MMVector), 0);
+            """))
     def gen_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
@@ -854,6 +869,11 @@ def decl_tcg(self, f, tag, regno):
                 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
                 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
+        """))
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
@@ -913,6 +933,11 @@ def decl_tcg(self, f, tag, regno):
                 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
                 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
+        """))
     def gen_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
@@ -946,6 +971,11 @@ def decl_tcg(self, f, tag, regno):
                 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
                 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                sizeof(MMQReg), sizeof(MMQReg), 0);
+        """))
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
@@ -993,6 +1023,11 @@ def decl_tcg(self, f, tag, regno):
                 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
                 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
             """))
+    def gen_zero(self, f):
+        f.write(code_fmt(f"""\
+            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
+                sizeof(MMQReg), sizeof(MMQReg), 0);
+        """))
     def gen_write(self, f, tag):
         pass
     def helper_hvx_desc(self, f):
-- 
2.37.2
Re: [PATCH v3 03/16] target/hexagon/cpu: add HVX IEEE FP extension
Posted by Taylor Simpson 2 days, 19 hours ago
On Wed, Apr 8, 2026 at 10:37 AM Matheus Tavares Bernardino <
matheus.bernardino@oss.qualcomm.com> wrote:

> This flag will be used to control the HVX IEEE float instructions, which
> are only available at some Hexagon cores. When unavailable, the
> instruction effectively only set the destination registers to 0.
>
> Signed-off-by: Matheus Tavares Bernardino <
> matheus.bernardino@oss.qualcomm.com>
> ---
>  target/hexagon/cpu.h             |  1 +
>  target/hexagon/translate.h       |  1 +
>  target/hexagon/attribs_def.h.inc |  3 +++
>  target/hexagon/cpu.c             |  1 +
>  target/hexagon/translate.c       |  1 +
>  target/hexagon/gen_tcg_funcs.py  | 11 ++++++++++
>  target/hexagon/hex_common.py     | 35 ++++++++++++++++++++++++++++++++
>  7 files changed, 53 insertions(+)
>
> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
> index 85afd59277..77822a48b6 100644
> --- a/target/hexagon/cpu.h
> +++ b/target/hexagon/cpu.h
> @@ -127,6 +127,7 @@ struct ArchCPU {
>      bool lldb_compat;
>      target_ulong lldb_stack_adjust;
>      bool short_circuit;
> +    bool ieee_fp_extension;
>  };
>
>  #include "cpu_bits.h"
> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
> index b37cb49238..516aab7038 100644
> --- a/target/hexagon/translate.h
> +++ b/target/hexagon/translate.h
> @@ -70,6 +70,7 @@ typedef struct DisasContext {
>      target_ulong branch_dest;
>      bool is_tight_loop;
>      bool short_circuit;
> +    bool ieee_fp_extension;
>      bool read_after_write;
>      bool has_hvx_overlap;
>      TCGv new_value[TOTAL_PER_THREAD_REGS];
> diff --git a/target/hexagon/attribs_def.h.inc
> b/target/hexagon/attribs_def.h.inc
> index 9e3a05f882..c85cd5d17c 100644
> --- a/target/hexagon/attribs_def.h.inc
> +++ b/target/hexagon/attribs_def.h.inc
> @@ -173,5 +173,8 @@ DEF_ATTRIB(NOTE_SHIFT_RESOURCE, "Uses the HVX shift
> resource.", "", "")
>  DEF_ATTRIB(RESTRICT_NOSLOT1_STORE, "Packet must not have slot 1 store",
> "", "")
>  DEF_ATTRIB(RESTRICT_LATEPRED, "Predicate can not be used as a .new.", "",
> "")
>
> +/* HVX IEEE FP extension attributes */
> +DEF_ATTRIB(HVX_IEEE_FP, "HVX IEEE FP extension instruction", "", "")
> +
>  /* Keep this as the last attribute: */
>  DEF_ATTRIB(ZZ_LASTATTRIB, "Last attribute in the file", "", "")
> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
> index ffd14bb467..8b72a5d3c8 100644
> --- a/target/hexagon/cpu.c
> +++ b/target/hexagon/cpu.c
> @@ -54,6 +54,7 @@ static const Property hexagon_cpu_properties[] = {
>      DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU,
> lldb_stack_adjust, 0,
>                           qdev_prop_uint32, target_ulong),
>      DEFINE_PROP_BOOL("short-circuit", HexagonCPU, short_circuit, true),
> +    DEFINE_PROP_BOOL("ieee-fp", HexagonCPU, ieee_fp_extension, true),
>  };
>
>  const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
> index 633401451d..fa8f615a9e 100644
> --- a/target/hexagon/translate.c
> +++ b/target/hexagon/translate.c
> @@ -988,6 +988,7 @@ static void
> hexagon_tr_init_disas_context(DisasContextBase *dcbase,
>      ctx->branch_cond = TCG_COND_NEVER;
>      ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
>      ctx->short_circuit = hex_cpu->short_circuit;
> +    ctx->ieee_fp_extension = hex_cpu->ieee_fp_extension;
>  }
>
>  static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
> diff --git a/target/hexagon/gen_tcg_funcs.py
> b/target/hexagon/gen_tcg_funcs.py
> index 87b7f10d7f..b752ec883c 100755
> --- a/target/hexagon/gen_tcg_funcs.py
> +++ b/target/hexagon/gen_tcg_funcs.py
> @@ -22,6 +22,14 @@
>  import string
>  import hex_common
>
> +def gen_disabled_ieee_insn(f, tag, regs):
> +    f.write("    if (!ctx->ieee_fp_extension) {\n")
> +    for regtype, regid in regs:
> +        reg = hex_common.get_register(tag, regtype, regid)
> +        if reg.is_hvx_reg() and reg.is_written():
> +            reg.gen_zero(f)
>

What happens to the non-HVX registers that are written (e.g., address for a
post-increment load)?  I assume they should also be set to zero.


> +    f.write("        return;\n")
> +    f.write("    }\n")
>
>  ##
>  ## Generate the TCG code to call the helper
> @@ -62,6 +70,9 @@ def gen_tcg_func(f, tag, regs, imms):
>          i = 1 if immlett.isupper() else 0
>          f.write(f"    int {hex_common.imm_name(immlett)} =
> insn->immed[{i}];\n")
>
> +    if "A_HVX_IEEE_FP" in hex_common.attribdict[tag]:
> +        gen_disabled_ieee_insn(f, tag, regs)
> +
>      if hex_common.is_idef_parser_enabled(tag):
>          declared = []
>          ## Handle registers
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index c0e9f26aeb..32a61505ce 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -723,6 +723,11 @@ def decl_tcg(self, f, tag, regno):
>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env,
> {self.hvx_off()});
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                    sizeof(MMVector), sizeof(MMVector), 0);
> +            """))
>      def gen_write(self, f, tag):
>          pass
>      def helper_hvx_desc(self, f):
> @@ -789,6 +794,11 @@ def decl_tcg(self, f, tag, regno):
>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env,
> {self.hvx_off()});
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                    sizeof(MMVector), sizeof(MMVector), 0);
> +            """))
>      def gen_write(self, f, tag):
>          pass
>      def helper_hvx_desc(self, f):
> @@ -821,6 +831,11 @@ def decl_tcg(self, f, tag, regno):
>                                   vreg_src_off(ctx, {self.reg_num}),
>                                   sizeof(MMVector), sizeof(MMVector));
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                    sizeof(MMVector), sizeof(MMVector), 0);
> +            """))
>      def gen_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
> @@ -854,6 +869,11 @@ def decl_tcg(self, f, tag, regno):
>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env,
> {self.hvx_off()});
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
> +        """))
>      def gen_write(self, f, tag):
>          pass
>      def helper_hvx_desc(self, f):
> @@ -913,6 +933,11 @@ def decl_tcg(self, f, tag, regno):
>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env,
> {self.hvx_off()});
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
> +        """))
>      def gen_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
> @@ -946,6 +971,11 @@ def decl_tcg(self, f, tag, regno):
>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env,
> {self.hvx_off()});
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                sizeof(MMQReg), sizeof(MMQReg), 0);
> +        """))
>

Do any of these instructions write QRegs?  If not, this isn't needed.


>      def gen_write(self, f, tag):
>          pass
>      def helper_hvx_desc(self, f):
> @@ -993,6 +1023,11 @@ def decl_tcg(self, f, tag, regno):
>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env,
> {self.hvx_off()});
>              """))
> +    def gen_zero(self, f):
> +        f.write(code_fmt(f"""\
> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
> +                sizeof(MMQReg), sizeof(MMQReg), 0);
> +        """))
>

Ditto


>      def gen_write(self, f, tag):
>          pass
>      def helper_hvx_desc(self, f):
> --
> 2.37.2
>
>
Re: [PATCH v3 03/16] target/hexagon/cpu: add HVX IEEE FP extension
Posted by Matheus Bernardino 1 day ago
On Wed, Apr 8, 2026 at 6:56 PM Taylor Simpson <ltaylorsimpson@gmail.com> wrote:
>
>
>
> On Wed, Apr 8, 2026 at 10:37 AM Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com> wrote:
>>
>> This flag will be used to control the HVX IEEE float instructions, which
>> are only available at some Hexagon cores. When unavailable, the
>> instruction effectively only set the destination registers to 0.
>>
>> Signed-off-by: Matheus Tavares Bernardino <matheus.bernardino@oss.qualcomm.com>
>> ---
>>  target/hexagon/cpu.h             |  1 +
>>  target/hexagon/translate.h       |  1 +
>>  target/hexagon/attribs_def.h.inc |  3 +++
>>  target/hexagon/cpu.c             |  1 +
>>  target/hexagon/translate.c       |  1 +
>>  target/hexagon/gen_tcg_funcs.py  | 11 ++++++++++
>>  target/hexagon/hex_common.py     | 35 ++++++++++++++++++++++++++++++++
>>  7 files changed, 53 insertions(+)
>>
>> diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
>> index 85afd59277..77822a48b6 100644
>> --- a/target/hexagon/cpu.h
>> +++ b/target/hexagon/cpu.h
>> @@ -127,6 +127,7 @@ struct ArchCPU {
>>      bool lldb_compat;
>>      target_ulong lldb_stack_adjust;
>>      bool short_circuit;
>> +    bool ieee_fp_extension;
>>  };
>>
>>  #include "cpu_bits.h"
>> diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
>> index b37cb49238..516aab7038 100644
>> --- a/target/hexagon/translate.h
>> +++ b/target/hexagon/translate.h
>> @@ -70,6 +70,7 @@ typedef struct DisasContext {
>>      target_ulong branch_dest;
>>      bool is_tight_loop;
>>      bool short_circuit;
>> +    bool ieee_fp_extension;
>>      bool read_after_write;
>>      bool has_hvx_overlap;
>>      TCGv new_value[TOTAL_PER_THREAD_REGS];
>> diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc
>> index 9e3a05f882..c85cd5d17c 100644
>> --- a/target/hexagon/attribs_def.h.inc
>> +++ b/target/hexagon/attribs_def.h.inc
>> @@ -173,5 +173,8 @@ DEF_ATTRIB(NOTE_SHIFT_RESOURCE, "Uses the HVX shift resource.", "", "")
>>  DEF_ATTRIB(RESTRICT_NOSLOT1_STORE, "Packet must not have slot 1 store", "", "")
>>  DEF_ATTRIB(RESTRICT_LATEPRED, "Predicate can not be used as a .new.", "", "")
>>
>> +/* HVX IEEE FP extension attributes */
>> +DEF_ATTRIB(HVX_IEEE_FP, "HVX IEEE FP extension instruction", "", "")
>> +
>>  /* Keep this as the last attribute: */
>>  DEF_ATTRIB(ZZ_LASTATTRIB, "Last attribute in the file", "", "")
>> diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
>> index ffd14bb467..8b72a5d3c8 100644
>> --- a/target/hexagon/cpu.c
>> +++ b/target/hexagon/cpu.c
>> @@ -54,6 +54,7 @@ static const Property hexagon_cpu_properties[] = {
>>      DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 0,
>>                           qdev_prop_uint32, target_ulong),
>>      DEFINE_PROP_BOOL("short-circuit", HexagonCPU, short_circuit, true),
>> +    DEFINE_PROP_BOOL("ieee-fp", HexagonCPU, ieee_fp_extension, true),
>>  };
>>
>>  const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
>> diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
>> index 633401451d..fa8f615a9e 100644
>> --- a/target/hexagon/translate.c
>> +++ b/target/hexagon/translate.c
>> @@ -988,6 +988,7 @@ static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
>>      ctx->branch_cond = TCG_COND_NEVER;
>>      ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
>>      ctx->short_circuit = hex_cpu->short_circuit;
>> +    ctx->ieee_fp_extension = hex_cpu->ieee_fp_extension;
>>  }
>>
>>  static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
>> diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
>> index 87b7f10d7f..b752ec883c 100755
>> --- a/target/hexagon/gen_tcg_funcs.py
>> +++ b/target/hexagon/gen_tcg_funcs.py
>> @@ -22,6 +22,14 @@
>>  import string
>>  import hex_common
>>
>> +def gen_disabled_ieee_insn(f, tag, regs):
>> +    f.write("    if (!ctx->ieee_fp_extension) {\n")
>> +    for regtype, regid in regs:
>> +        reg = hex_common.get_register(tag, regtype, regid)
>> +        if reg.is_hvx_reg() and reg.is_written():
>> +            reg.gen_zero(f)
>
>
> What happens to the non-HVX registers that are written (e.g., address for a post-increment load)?  I assume they should also be set to zero.

None of these instructions write to non-HVX registers.

>>
>> +    f.write("        return;\n")
>> +    f.write("    }\n")
>>
>>  ##
>>  ## Generate the TCG code to call the helper
>> @@ -62,6 +70,9 @@ def gen_tcg_func(f, tag, regs, imms):
>>          i = 1 if immlett.isupper() else 0
>>          f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
>>
>> +    if "A_HVX_IEEE_FP" in hex_common.attribdict[tag]:
>> +        gen_disabled_ieee_insn(f, tag, regs)
>> +
>>      if hex_common.is_idef_parser_enabled(tag):
>>          declared = []
>>          ## Handle registers
>> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
>> index c0e9f26aeb..32a61505ce 100755
>> --- a/target/hexagon/hex_common.py
>> +++ b/target/hexagon/hex_common.py
>> @@ -723,6 +723,11 @@ def decl_tcg(self, f, tag, regno):
>>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
>>              """))
>> +    def gen_zero(self, f):
>> +        f.write(code_fmt(f"""\
>> +                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
>> +                    sizeof(MMVector), sizeof(MMVector), 0);
>> +            """))
>>      def gen_write(self, f, tag):
>>          pass
>>      def helper_hvx_desc(self, f):
>> @@ -789,6 +794,11 @@ def decl_tcg(self, f, tag, regno):
>>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
>>              """))
>> +    def gen_zero(self, f):
>> +        f.write(code_fmt(f"""\
>> +                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
>> +                    sizeof(MMVector), sizeof(MMVector), 0);
>> +            """))
>>      def gen_write(self, f, tag):
>>          pass
>>      def helper_hvx_desc(self, f):
>> @@ -821,6 +831,11 @@ def decl_tcg(self, f, tag, regno):
>>                                   vreg_src_off(ctx, {self.reg_num}),
>>                                   sizeof(MMVector), sizeof(MMVector));
>>              """))
>> +    def gen_zero(self, f):
>> +        f.write(code_fmt(f"""\
>> +                tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
>> +                    sizeof(MMVector), sizeof(MMVector), 0);
>> +            """))
>>      def gen_write(self, f, tag):
>>          f.write(code_fmt(f"""\
>>              gen_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
>> @@ -854,6 +869,11 @@ def decl_tcg(self, f, tag, regno):
>>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
>>              """))
>> +    def gen_zero(self, f):
>> +        f.write(code_fmt(f"""\
>> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
>> +                sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
>> +        """))
>>      def gen_write(self, f, tag):
>>          pass
>>      def helper_hvx_desc(self, f):
>> @@ -913,6 +933,11 @@ def decl_tcg(self, f, tag, regno):
>>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
>>              """))
>> +    def gen_zero(self, f):
>> +        f.write(code_fmt(f"""\
>> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
>> +                sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
>> +        """))
>>      def gen_write(self, f, tag):
>>          f.write(code_fmt(f"""\
>>              gen_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
>> @@ -946,6 +971,11 @@ def decl_tcg(self, f, tag, regno):
>>                  TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
>>                  tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
>>              """))
>> +    def gen_zero(self, f):
>> +        f.write(code_fmt(f"""\
>> +            tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
>> +                sizeof(MMQReg), sizeof(MMQReg), 0);
>> +        """))
>
>
> Do any of these instructions write QRegs?  If not, this isn't needed.

They do not. Let me remove this.