@samitouri / QOSamiQemu / commits / e1245d0ea4

target/hexagon/cpu: add HVX IEEE FP extension

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> Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com> Link: https://lore.kernel.org/qemu-devel/10fb5b86db60a465e51db2cf73185307a1ec0895.1776339451.git.matheus.bernardino@oss.qualcomm.com Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

Matheus Tavares Bernardino committed Apr 16, 2026 at 04:38 UTC e1245d0ea4552895429a10e6eb51f148cea4d4c0
7 files changed +44
target/hexagon/attribs_def.h.inc
+3
@@ -196,5 +196,8 @@ DEF_ATTRIB(NOTE_SHIFT_RESOURCE, "Uses the HVX shift resource.", "", "")
196 DEF_ATTRIB(RESTRICT_NOSLOT1_STORE, "Packet must not have slot 1 store", "", "")
197 DEF_ATTRIB(RESTRICT_LATEPRED, "Predicate can not be used as a .new.", "", "")
198
199 +/* HVX IEEE FP extension attributes */
200 +DEF_ATTRIB(HVX_IEEE_FP, "HVX IEEE FP extension instruction", "", "")
201 +
202 /* Keep this as the last attribute: */
203 DEF_ATTRIB(ZZ_LASTATTRIB, "Last attribute in the file", "", "")
target/hexagon/cpu.c
+1
@@ -75,6 +75,7 @@ static const Property hexagon_cpu_properties[] = {
75 DEFINE_PROP_UNSIGNED("lldb-stack-adjust", HexagonCPU, lldb_stack_adjust, 0,
76 qdev_prop_uint32, target_ulong),
77 DEFINE_PROP_BOOL("short-circuit", HexagonCPU, short_circuit, true),
78 + DEFINE_PROP_BOOL("ieee-fp", HexagonCPU, ieee_fp_extension, true),
79 };
80
81 const char * const hexagon_regnames[TOTAL_PER_THREAD_REGS] = {
target/hexagon/cpu.h
+1
@@ -194,6 +194,7 @@ struct ArchCPU {
194 bool lldb_compat;
195 target_ulong lldb_stack_adjust;
196 bool short_circuit;
197 + bool ieee_fp_extension;
198 #ifndef CONFIG_USER_ONLY
199 HexagonTLBState *tlb;
200 uint32_t boot_addr;
target/hexagon/gen_tcg_funcs.py
+12
@@ -23,6 +23,15 @@ import string
23 import hex_common
24 from textwrap import dedent
25
26 +def gen_disabled_ieee_insn(f, tag, regs):
27 + f.write(" if (!ctx->ieee_fp_extension) {\n")
28 + for regtype, regid in regs:
29 + reg = hex_common.get_register(tag, regtype, regid)
30 + if reg.is_hvx_reg() and reg.is_written():
31 + reg.gen_zero(f)
32 + f.write(" return;\n")
33 + f.write(" }\n")
34 +
35 ##
36 ## Generate the TCG code to call the helper
37 ## For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
@@ -74,6 +83,9 @@ def gen_tcg_func(f, tag, regs, imms):
83 i = 1 if immlett.isupper() else 0
84 f.write(f" int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
85
86 + if "A_HVX_IEEE_FP" in hex_common.attribdict[tag]:
87 + gen_disabled_ieee_insn(f, tag, regs)
88 +
89 if hex_common.is_idef_parser_enabled(tag):
90 gpr_operands = [
91 hex_common.get_register(tag, regtype, regid)
target/hexagon/hex_common.py
+25
@@ -784,6 +784,11 @@ class VRegDest(Register, Hvx, Dest):
784 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
785 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
786 """))
787 + def gen_zero(self, f):
788 + f.write(code_fmt(f"""\
789 + tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
790 + sizeof(MMVector), sizeof(MMVector), 0);
791 + """))
792 def gen_write(self, f, tag):
793 pass
794 def helper_hvx_desc(self, f):
@@ -850,6 +855,11 @@ class VRegReadWrite(Register, Hvx, ReadWrite):
855 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
856 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
857 """))
858 + def gen_zero(self, f):
859 + f.write(code_fmt(f"""\
860 + tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
861 + sizeof(MMVector), sizeof(MMVector), 0);
862 + """))
863 def gen_write(self, f, tag):
864 pass
865 def helper_hvx_desc(self, f):
@@ -882,6 +892,11 @@ class VRegTmp(Register, Hvx, ReadWrite):
892 vreg_src_off(ctx, {self.reg_num}),
893 sizeof(MMVector), sizeof(MMVector));
894 """))
895 + def gen_zero(self, f):
896 + f.write(code_fmt(f"""\
897 + tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
898 + sizeof(MMVector), sizeof(MMVector), 0);
899 + """))
900 def gen_write(self, f, tag):
901 f.write(code_fmt(f"""\
902 gen_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
@@ -915,6 +930,11 @@ class VRegPairDest(Register, Hvx, Dest):
930 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
931 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
932 """))
933 + def gen_zero(self, f):
934 + f.write(code_fmt(f"""\
935 + tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
936 + sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
937 + """))
938 def gen_write(self, f, tag):
939 pass
940 def helper_hvx_desc(self, f):
@@ -974,6 +994,11 @@ class VRegPairReadWrite(Register, Hvx, ReadWrite):
994 TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
995 tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
996 """))
997 + def gen_zero(self, f):
998 + f.write(code_fmt(f"""\
999 + tcg_gen_gvec_dup_imm(MO_64, {self.hvx_off()},
1000 + sizeof(MMVectorPair), sizeof(MMVectorPair), 0);
1001 + """))
1002 def gen_write(self, f, tag):
1003 f.write(code_fmt(f"""\
1004 gen_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
target/hexagon/translate.c
+1
@@ -1211,6 +1211,7 @@ static void hexagon_tr_init_disas_context(DisasContextBase *dcbase,
1211 ctx->is_tight_loop = FIELD_EX32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP);
1212 ctx->short_circuit = hex_cpu->short_circuit;
1213 ctx->hex_def = HEXAGON_CPU_GET_CLASS(hex_cpu)->hex_def;
1214 + ctx->ieee_fp_extension = hex_cpu->ieee_fp_extension;
1215 #ifndef CONFIG_USER_ONLY
1216 ctx->num_cycles = 0;
1217 ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS, PCYCLE_ENABLED);
target/hexagon/translate.h
+1
@@ -81,6 +81,7 @@ typedef struct DisasContext {
81 target_ulong branch_dest;
82 bool is_tight_loop;
83 bool short_circuit;
84 + bool ieee_fp_extension;
85 bool read_after_write;
86 bool has_hvx_overlap;
87 TCGv new_value[TOTAL_PER_THREAD_REGS];