All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented
@ 2023-12-10 22:07 Taylor Simpson
  2023-12-10 22:07 ` [PATCH v2 1/9] Hexagon (target/hexagon) Clean up handling of modifier registers Taylor Simpson
                   ` (9 more replies)
  0 siblings, 10 replies; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

See commit message in second patch

**** Changes in v2 ****
Address feedback from Brian Cain <bcain@quicinc.com>
- Consolidate logic to create helper arg lists


Taylor Simpson (9):
  Hexagon (target/hexagon) Clean up handling of modifier registers
  Hexagon (target/hexagon) Make generators object oriented -
    gen_tcg_funcs
  Hexagon (target/hexagon) Make generators object oriented -
    gen_helper_protos
  Hexagon (target/hexagon) Make generators object oriented -
    gen_helper_funcs
  Hexagon (target/hexagon) Make generators object oriented -
    gen_idef_parser_funcs
  Hexagon (target/hexagon) Make generators object oriented - gen_op_regs
  Hexagon (target/hexagon) Make generators object oriented -
    gen_analyze_funcs
  Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute
  Hexagon (target/hexagon) Remove dead functions from hex_common.py

 target/hexagon/gen_tcg.h                    |   9 +-
 target/hexagon/macros.h                     |   3 +-
 target/hexagon/attribs_def.h.inc            |   1 -
 target/hexagon/idef-parser/parser-helpers.c |   8 +-
 target/hexagon/gen_analyze_funcs.py         | 163 +---
 target/hexagon/gen_helper_funcs.py          | 368 ++------
 target/hexagon/gen_helper_protos.py         | 149 +---
 target/hexagon/gen_idef_parser_funcs.py     |  20 +-
 target/hexagon/gen_op_regs.py               |   6 +-
 target/hexagon/gen_tcg_funcs.py             | 566 +-----------
 target/hexagon/hex_common.py                | 921 ++++++++++++++++++--
 11 files changed, 964 insertions(+), 1250 deletions(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/9] Hexagon (target/hexagon) Clean up handling of modifier registers
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2023-12-10 22:07 ` [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs Taylor Simpson
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

Currently, the register number (MuN) for modifier registers is the
modifier register number rather than the index into hex_gpr.  This
patch changes MuN to the hex_gpr index, which is consistent with
the handling of control registers.

Note that HELPER(fcircadd) needs the CS register corresponding to the
modifier register specified in the instruction.  We create a TCGv
variable "CS" to hold the value to pass to the helper.

Reviewed-by: Brian Cain <bcain@quicinc.com>
Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_tcg.h                    |  9 ++++-----
 target/hexagon/macros.h                     |  3 +--
 target/hexagon/idef-parser/parser-helpers.c |  8 +++-----
 target/hexagon/gen_tcg_funcs.py             | 13 +++++++++----
 4 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index d992059fce..1c4391b415 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -68,15 +68,14 @@
     do { \
         TCGv tcgv_siV = tcg_constant_tl(siV); \
         tcg_gen_mov_tl(EA, RxV); \
-        gen_helper_fcircadd(RxV, RxV, tcgv_siV, MuV, \
-                            hex_gpr[HEX_REG_CS0 + MuN]); \
+        gen_helper_fcircadd(RxV, RxV, tcgv_siV, MuV, CS); \
     } while (0)
 #define GET_EA_pcr(SHIFT) \
     do { \
         TCGv ireg = tcg_temp_new(); \
         tcg_gen_mov_tl(EA, RxV); \
         gen_read_ireg(ireg, MuV, (SHIFT)); \
-        gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
+        gen_helper_fcircadd(RxV, RxV, ireg, MuV, CS); \
     } while (0)
 
 /* Instructions with multiple definitions */
@@ -113,7 +112,7 @@
         TCGv ireg = tcg_temp_new(); \
         tcg_gen_mov_tl(EA, RxV); \
         gen_read_ireg(ireg, MuV, SHIFT); \
-        gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
+        gen_helper_fcircadd(RxV, RxV, ireg, MuV, CS); \
         LOAD; \
     } while (0)
 
@@ -427,7 +426,7 @@
         TCGv BYTE G_GNUC_UNUSED = tcg_temp_new(); \
         tcg_gen_mov_tl(EA, RxV); \
         gen_read_ireg(ireg, MuV, SHIFT); \
-        gen_helper_fcircadd(RxV, RxV, ireg, MuV, hex_gpr[HEX_REG_CS0 + MuN]); \
+        gen_helper_fcircadd(RxV, RxV, ireg, MuV, CS); \
         STORE; \
     } while (0)
 
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 9a51b5709b..939f22e76b 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -462,8 +462,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
 #define fPM_CIRI(REG, IMM, MVAL) \
     do { \
         TCGv tcgv_siV = tcg_constant_tl(siV); \
-        gen_helper_fcircadd(REG, REG, tcgv_siV, MuV, \
-                            hex_gpr[HEX_REG_CS0 + MuN]); \
+        gen_helper_fcircadd(REG, REG, tcgv_siV, MuV, CS); \
     } while (0)
 #else
 #define fEA_IMM(IMM)        do { EA = (IMM); } while (0)
diff --git a/target/hexagon/idef-parser/parser-helpers.c b/target/hexagon/idef-parser/parser-helpers.c
index 4af020933a..95f2b43076 100644
--- a/target/hexagon/idef-parser/parser-helpers.c
+++ b/target/hexagon/idef-parser/parser-helpers.c
@@ -1541,10 +1541,8 @@ void gen_circ_op(Context *c,
                  HexValue *increment,
                  HexValue *modifier)
 {
-    HexValue cs = gen_tmp(c, locp, 32, UNSIGNED);
     HexValue increment_m = *increment;
     increment_m = rvalue_materialize(c, locp, &increment_m);
-    OUT(c, locp, "gen_read_reg(", &cs, ", HEX_REG_CS0 + MuN);\n");
     OUT(c,
         locp,
         "gen_helper_fcircadd(",
@@ -1555,7 +1553,7 @@ void gen_circ_op(Context *c,
         &increment_m,
         ", ",
         modifier);
-    OUT(c, locp, ", ", &cs, ");\n");
+    OUT(c, locp, ", CS);\n");
 }
 
 HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src)
@@ -2080,9 +2078,9 @@ void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg)
             char reg_id[5];
             reg_compose(c, locp, &(arg->reg), reg_id);
             EMIT_SIG(c, ", %s %s", type, reg_id);
-            /* MuV register requires also MuN to provide its index */
+            /* MuV register requires also CS for circular addressing*/
             if (arg->reg.type == MODIFIER) {
-                EMIT_SIG(c, ", int MuN");
+                EMIT_SIG(c, ", TCGv CS");
             }
         }
         break;
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index f5246cee6d..02d93bc5ce 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -99,10 +99,15 @@ def genptr_decl(f, tag, regtype, regid, regno):
             hex_common.bad_register(regtype, regid)
     elif regtype == "M":
         if regid == "u":
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
             f.write(
-                f"    TCGv {regtype}{regid}V = hex_gpr[{regtype}{regid}N + "
-                "HEX_REG_M0];\n"
+                f"    const int {regN} = insn->regno[{regno}] + HEX_REG_M0;\n"
+            )
+            f.write(
+                f"    TCGv {regtype}{regid}V = hex_gpr[{regN}];\n"
+            )
+            f.write(
+                f"    TCGv CS G_GNUC_UNUSED = "
+                f"hex_gpr[{regN} - HEX_REG_M0 + HEX_REG_CS0];\n"
             )
         else:
             hex_common.bad_register(regtype, regid)
@@ -528,7 +533,7 @@ def gen_tcg_func(f, tag, regs, imms):
             ):
                 declared.append(f"{regtype}{regid}V")
                 if regtype == "M":
-                    declared.append(f"{regtype}{regid}N")
+                    declared.append("CS")
             elif hex_common.is_new_val(regtype, regid, tag):
                 declared.append(f"{regtype}{regid}N")
             else:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
  2023-12-10 22:07 ` [PATCH v2 1/9] Hexagon (target/hexagon) Clean up handling of modifier registers Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:08   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos Taylor Simpson
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

The generators are generally a bunch of Python if-then-else
statements based on the regtype and regid.  Encapsulate regtype/regid
into a class hierarchy.  Clients lookup the register and invoke
methods.

This has several advantages for making the code easier to read,
understand, and maintain
- The class name makes it more clear what the operand does
- All the methods for a given type of operand are together
- Don't need hex_common.bad_register
  If a regtype/regid is missing, the lookup in hex_common.get_register
  will fail
- We can remove the functions in hex_common that use regtype/regid
  (e.g., is_read)

This patch creates the class hierarchy in hex_common and converts
gen_tcg_funcs.py.  The other scripts will be converted in subsequent
patches in this series.

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_tcg_funcs.py | 571 ++-------------------------
 target/hexagon/hex_common.py    | 659 ++++++++++++++++++++++++++++++++
 2 files changed, 683 insertions(+), 547 deletions(-)

diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 02d93bc5ce..3d8e3cb6a2 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -23,466 +23,13 @@
 import hex_common
 
 
-##
-## Helpers for gen_tcg_func
-##
-def gen_decl_ea_tcg(f, tag):
-    f.write("    TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
-
-
-def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
-    regN = f"{regtype}{regid}N"
-    if regtype == "R":
-        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-    elif regtype == "C":
-        f.write(f"    const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n")
-    else:
-        hex_common.bad_register(regtype, regid)
-    f.write(f"    TCGv_i64 {regtype}{regid}V = " f"get_result_gpr_pair(ctx, {regN});\n")
-
-
-def genptr_decl_writable(f, tag, regtype, regid, regno):
-    regN = f"{regtype}{regid}N"
-    if regtype == "R":
-        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-        f.write(f"    TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
-    elif regtype == "C":
-        f.write(f"    const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n")
-        f.write(f"    TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
-    elif regtype == "P":
-        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-        f.write(f"    TCGv {regtype}{regid}V = tcg_temp_new();\n")
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_decl(f, tag, regtype, regid, regno):
-    regN = f"{regtype}{regid}N"
-    if regtype == "R":
-        if regid in {"ss", "tt"}:
-            f.write(f"    TCGv_i64 {regtype}{regid}V = tcg_temp_new_i64();\n")
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"dd", "ee", "xx", "yy"}:
-            genptr_decl_pair_writable(f, tag, regtype, regid, regno)
-        elif regid in {"s", "t", "u", "v"}:
-            f.write(
-                f"    TCGv {regtype}{regid}V = " f"hex_gpr[insn->regno[{regno}]];\n"
-            )
-        elif regid in {"d", "e", "x", "y"}:
-            genptr_decl_writable(f, tag, regtype, regid, regno)
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid in {"s", "t", "u", "v"}:
-            f.write(
-                f"    TCGv {regtype}{regid}V = " f"hex_pred[insn->regno[{regno}]];\n"
-            )
-        elif regid in {"d", "e", "x"}:
-            genptr_decl_writable(f, tag, regtype, regid, regno)
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "C":
-        if regid == "ss":
-            f.write(f"    TCGv_i64 {regtype}{regid}V = " f"tcg_temp_new_i64();\n")
-            f.write(f"    const int {regN} = insn->regno[{regno}] + " "HEX_REG_SA0;\n")
-        elif regid == "dd":
-            genptr_decl_pair_writable(f, tag, regtype, regid, regno)
-        elif regid == "s":
-            f.write(f"    TCGv {regtype}{regid}V = tcg_temp_new();\n")
-            f.write(
-                f"    const int {regtype}{regid}N = insn->regno[{regno}] + "
-                "HEX_REG_SA0;\n"
-            )
-        elif regid == "d":
-            genptr_decl_writable(f, tag, regtype, regid, regno)
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "M":
-        if regid == "u":
-            f.write(
-                f"    const int {regN} = insn->regno[{regno}] + HEX_REG_M0;\n"
-            )
-            f.write(
-                f"    TCGv {regtype}{regid}V = hex_gpr[{regN}];\n"
-            )
-            f.write(
-                f"    TCGv CS G_GNUC_UNUSED = "
-                f"hex_gpr[{regN} - HEX_REG_M0 + HEX_REG_CS0];\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "V":
-        if regid in {"dd"}:
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
-            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
-            if hex_common.is_tmp_result(tag):
-                f.write(
-                    f"        ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 2, " "true);\n"
-                )
-            else:
-                f.write(f"        ctx_future_vreg_off(ctx, {regtype}{regid}N,")
-                f.write(" 2, true);\n")
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
-                f.write(
-                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
-                    f"{regtype}{regid}V_off);\n"
-                )
-        elif regid in {"uu", "vv", "xx"}:
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
-            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
-            f.write(f"        offsetof(CPUHexagonState, {regtype}{regid}V);\n")
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
-                f.write(
-                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
-                    f"{regtype}{regid}V_off);\n"
-                )
-        elif regid in {"s", "u", "v", "w"}:
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
-            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
-            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N);\n")
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
-        elif regid in {"d", "x", "y"}:
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
-            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
-            if regid == "y":
-                f.write("        offsetof(CPUHexagonState, vtmp);\n")
-            elif hex_common.is_tmp_result(tag):
-                f.write(
-                    f"        ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 1, " "true);\n"
-                )
-            else:
-                f.write(f"        ctx_future_vreg_off(ctx, {regtype}{regid}N,")
-                f.write(" 1, true);\n")
-
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
-                f.write(
-                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
-                    f"{regtype}{regid}V_off);\n"
-                )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "Q":
-        if regid in {"d", "e", "x"}:
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
-            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
-            f.write(f"        get_result_qreg(ctx, {regtype}{regid}N);\n")
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
-                f.write(
-                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
-                    f"{regtype}{regid}V_off);\n"
-                )
-        elif regid in {"s", "t", "u", "v"}:
-            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
-            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
-            f.write(
-                f"        offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]);\n"
-            )
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_decl_new(f, tag, regtype, regid, regno):
-    if regtype == "N":
-        if regid in {"s", "t"}:
-            f.write(
-                f"    TCGv {regtype}{regid}N = "
-                f"get_result_gpr(ctx, insn->regno[{regno}]);\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid in {"t", "u", "v"}:
-            f.write(
-                f"    TCGv {regtype}{regid}N = "
-                f"ctx->new_pred_value[insn->regno[{regno}]];\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "O":
-        if regid == "s":
-            f.write(
-                f"    const intptr_t {regtype}{regid}N_num = "
-                f"insn->regno[{regno}];\n"
-            )
-            if hex_common.skip_qemu_helper(tag):
-                f.write(f"    const intptr_t {regtype}{regid}N_off =\n")
-                f.write("         ctx_future_vreg_off(ctx, " f"{regtype}{regid}N_num,")
-                f.write(" 1, true);\n")
-            else:
-                f.write(
-                    f"    TCGv {regtype}{regid}N = "
-                    f"tcg_constant_tl({regtype}{regid}N_num);\n"
-                )
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_decl_opn(f, tag, regtype, regid, i):
-    if hex_common.is_pair(regid):
-        genptr_decl(f, tag, regtype, regid, i)
-    elif hex_common.is_single(regid):
-        if hex_common.is_old_val(regtype, regid, tag):
-            genptr_decl(f, tag, regtype, regid, i)
-        elif hex_common.is_new_val(regtype, regid, tag):
-            genptr_decl_new(f, tag, regtype, regid, i)
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_decl_imm(f, immlett):
-    if immlett.isupper():
-        i = 1
-    else:
-        i = 0
-    f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
-
-
-def genptr_src_read(f, tag, regtype, regid):
-    if regtype == "R":
-        if regid in {"ss", "tt", "xx", "yy"}:
-            f.write(
-                f"    tcg_gen_concat_i32_i64({regtype}{regid}V, "
-                f"hex_gpr[{regtype}{regid}N],\n"
-            )
-            f.write(
-                f"                                 hex_gpr[{regtype}"
-                f"{regid}N + 1]);\n"
-            )
-        elif regid in {"x", "y"}:
-            ## For read/write registers, we need to get the original value into
-            ## the result TCGv.  For conditional instructions, this is done in
-            ## gen_start_packet.  For unconditional instructions, we do it here.
-            if "A_CONDEXEC" not in hex_common.attribdict[tag]:
-                f.write(
-                    f"    tcg_gen_mov_tl({regtype}{regid}V, "
-                    f"hex_gpr[{regtype}{regid}N]);\n"
-                )
-        elif regid not in {"s", "t", "u", "v"}:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid == "x":
-            f.write(
-                f"    tcg_gen_mov_tl({regtype}{regid}V, "
-                f"hex_pred[{regtype}{regid}N]);\n"
-            )
-        elif regid not in {"s", "t", "u", "v"}:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "C":
-        if regid == "ss":
-            f.write(
-                f"    gen_read_ctrl_reg_pair(ctx, {regtype}{regid}N, "
-                f"{regtype}{regid}V);\n"
-            )
-        elif regid == "s":
-            f.write(
-                f"    gen_read_ctrl_reg(ctx, {regtype}{regid}N, "
-                f"{regtype}{regid}V);\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "M":
-        if regid != "u":
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "V":
-        if regid in {"uu", "vv", "xx"}:
-            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
-            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N),\n")
-            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
-            f.write("    tcg_gen_gvec_mov(MO_64,\n")
-            f.write(f"        {regtype}{regid}V_off + sizeof(MMVector),\n")
-            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N ^ 1),\n")
-            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
-        elif regid in {"s", "u", "v", "w"}:
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(
-                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
-                    f"{regtype}{regid}V_off);\n"
-                )
-        elif regid in {"x", "y"}:
-            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
-            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N),\n")
-            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "Q":
-        if regid in {"s", "t", "u", "v"}:
-            if not hex_common.skip_qemu_helper(tag):
-                f.write(
-                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
-                    f"{regtype}{regid}V_off);\n"
-                )
-        elif regid in {"x"}:
-            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
-            f.write(
-                f"        offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]),\n"
-            )
-            f.write("        sizeof(MMQReg), sizeof(MMQReg));\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_src_read_new(f, regtype, regid):
-    if regtype == "N":
-        if regid not in {"s", "t"}:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid not in {"t", "u", "v"}:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "O":
-        if regid != "s":
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_src_read_opn(f, regtype, regid, tag):
-    if hex_common.is_pair(regid):
-        genptr_src_read(f, tag, regtype, regid)
-    elif hex_common.is_single(regid):
-        if hex_common.is_old_val(regtype, regid, tag):
-            genptr_src_read(f, tag, regtype, regid)
-        elif hex_common.is_new_val(regtype, regid, tag):
-            genptr_src_read_new(f, regtype, regid)
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def gen_helper_call_opn(f, tag, regtype, regid, i):
-    if i > 0:
-        f.write(", ")
-    if hex_common.is_pair(regid):
-        f.write(f"{regtype}{regid}V")
-    elif hex_common.is_single(regid):
-        if hex_common.is_old_val(regtype, regid, tag):
-            f.write(f"{regtype}{regid}V")
-        elif hex_common.is_new_val(regtype, regid, tag):
-            f.write(f"{regtype}{regid}N")
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def gen_helper_decl_imm(f, immlett):
-    f.write(
-        f"    TCGv tcgv_{hex_common.imm_name(immlett)} = "
-        f"tcg_constant_tl({hex_common.imm_name(immlett)});\n"
-    )
-
-
-def gen_helper_call_imm(f, immlett):
-    f.write(f", tcgv_{hex_common.imm_name(immlett)}")
-
-
-def genptr_dst_write_pair(f, tag, regtype, regid):
-    f.write(f"    gen_log_reg_write_pair(ctx, {regtype}{regid}N, "
-            f"{regtype}{regid}V);\n")
-
-
-def genptr_dst_write(f, tag, regtype, regid):
-    if regtype == "R":
-        if regid in {"dd", "xx", "yy"}:
-            genptr_dst_write_pair(f, tag, regtype, regid)
-        elif regid in {"d", "e", "x", "y"}:
-            f.write(
-                f"    gen_log_reg_write(ctx, {regtype}{regid}N, "
-                f"{regtype}{regid}V);\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid in {"d", "e", "x"}:
-            f.write(
-                f"    gen_log_pred_write(ctx, {regtype}{regid}N, "
-                f"{regtype}{regid}V);\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "C":
-        if regid == "dd":
-            f.write(
-                f"    gen_write_ctrl_reg_pair(ctx, {regtype}{regid}N, "
-                f"{regtype}{regid}V);\n"
-            )
-        elif regid == "d":
-            f.write(
-                f"    gen_write_ctrl_reg(ctx, {regtype}{regid}N, "
-                f"{regtype}{regid}V);\n"
-            )
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"):
-    if regtype == "V":
-        if regid in {"xx"}:
-            f.write(
-                f"    gen_log_vreg_write_pair(ctx, {regtype}{regid}V_off, "
-                f"{regtype}{regid}N, {newv});\n"
-            )
-        elif regid in {"y"}:
-            f.write(
-                f"    gen_log_vreg_write(ctx, {regtype}{regid}V_off, "
-                f"{regtype}{regid}N, {newv});\n"
-            )
-        elif regid not in {"dd", "d", "x"}:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "Q":
-        if regid not in {"d", "e", "x"}:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def genptr_dst_write_opn(f, regtype, regid, tag):
-    if hex_common.is_pair(regid):
-        if hex_common.is_hvx_reg(regtype):
-            if hex_common.is_tmp_result(tag):
-                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
-            else:
-                genptr_dst_write_ext(f, tag, regtype, regid)
-        else:
-            genptr_dst_write(f, tag, regtype, regid)
-    elif hex_common.is_single(regid):
-        if hex_common.is_hvx_reg(regtype):
-            if hex_common.is_new_result(tag):
-                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW")
-            elif hex_common.is_tmp_result(tag):
-                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
-            else:
-                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL")
-        else:
-            genptr_dst_write(f, tag, regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
 ##
 ## Generate the TCG code to call the helper
 ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
 ##     We produce:
 ##    static void generate_A2_add(DisasContext *ctx)
 ##    {
-##        Insn *insn __attribute__((unused)) = ctx->insn;
+##        Insn *insn G_GNUC_UNUSED = ctx->insn;
 ##        const int RdN = insn->regno[0];
 ##        TCGv RdV = get_result_gpr(ctx, RdN);
 ##        TCGv RsV = hex_gpr[insn->regno[1]];
@@ -501,44 +48,27 @@ def gen_tcg_func(f, tag, regs, imms):
     f.write(f"static void generate_{tag}(DisasContext *ctx)\n")
     f.write("{\n")
 
-    f.write("    Insn *insn __attribute__((unused)) = ctx->insn;\n")
+    f.write("    Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
 
     if hex_common.need_ea(tag):
-        gen_decl_ea_tcg(f, tag)
-    i = 0
+        f.write("    TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
+
     ## Declare all the operands (regs and immediates)
+    i = 0
     for regtype, regid in regs:
-        genptr_decl_opn(f, tag, regtype, regid, i)
+        reg = hex_common.get_register(tag, regtype, regid)
+        reg.decl_tcg(f, tag, i)
         i += 1
     for immlett, bits, immshift in imms:
-        genptr_decl_imm(f, immlett)
-
-    if "A_PRIV" in hex_common.attribdict[tag]:
-        f.write("    fCHECKFORPRIV();\n")
-    if "A_GUEST" in hex_common.attribdict[tag]:
-        f.write("    fCHECKFORGUEST();\n")
-
-    ## Read all the inputs
-    for regtype, regid in regs:
-        if hex_common.is_read(regid):
-            genptr_src_read_opn(f, regtype, regid, tag)
+        i = 1 if immlett.isupper() else 0
+        f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
 
     if hex_common.is_idef_parser_enabled(tag):
         declared = []
         ## Handle registers
         for regtype, regid in regs:
-            if hex_common.is_pair(regid) or (
-                hex_common.is_single(regid)
-                and hex_common.is_old_val(regtype, regid, tag)
-            ):
-                declared.append(f"{regtype}{regid}V")
-                if regtype == "M":
-                    declared.append("CS")
-            elif hex_common.is_new_val(regtype, regid, tag):
-                declared.append(f"{regtype}{regid}N")
-            else:
-                hex_common.bad_register(regtype, regid)
-
+            reg = hex_common.get_register(tag, regtype, regid)
+            reg.idef_arg(declared)
         ## Handle immediates
         for immlett, bits, immshift in imms:
             declared.append(hex_common.imm_name(immlett))
@@ -550,76 +80,22 @@ def gen_tcg_func(f, tag, regs, imms):
         f.write(f"    fGEN_TCG_{tag}({hex_common.semdict[tag]});\n")
     else:
         ## Generate the call to the helper
-        for immlett, bits, immshift in imms:
-            gen_helper_decl_imm(f, immlett)
-        if hex_common.need_pkt_has_multi_cof(tag):
-            f.write("    TCGv pkt_has_multi_cof = ")
-            f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n")
-        if hex_common.need_pkt_need_commit(tag):
-            f.write("    TCGv pkt_need_commit = ")
-            f.write("tcg_constant_tl(ctx->need_commit);\n")
-        if hex_common.need_part1(tag):
-            f.write("    TCGv part1 = tcg_constant_tl(insn->part1);\n")
-        if hex_common.need_slot(tag):
-            f.write("    TCGv slotval = gen_slotval(ctx);\n")
-        if hex_common.need_PC(tag):
-            f.write("    TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
-        if hex_common.helper_needs_next_PC(tag):
-            f.write("    TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n")
-        f.write(f"    gen_helper_{tag}(")
-        i = 0
-        ## If there is a scalar result, it is the return type
-        for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                if hex_common.is_hvx_reg(regtype):
-                    continue
-                gen_helper_call_opn(f, tag, regtype, regid, i)
-                i += 1
-        if i > 0:
-            f.write(", ")
-        f.write("tcg_env")
-        i = 1
-        ## For conditional instructions, we pass in the destination register
-        if "A_CONDEXEC" in hex_common.attribdict[tag]:
-            for regtype, regid in regs:
-                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
-                    regtype
-                ):
-                    gen_helper_call_opn(f, tag, regtype, regid, i)
-                    i += 1
-        for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                if not hex_common.is_hvx_reg(regtype):
-                    continue
-                gen_helper_call_opn(f, tag, regtype, regid, i)
-                i += 1
-        for regtype, regid in regs:
-            if hex_common.is_read(regid):
-                if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
-                    continue
-                gen_helper_call_opn(f, tag, regtype, regid, i)
-                i += 1
-        for immlett, bits, immshift in imms:
-            gen_helper_call_imm(f, immlett)
+        declared = []
+        ret_type = hex_common.helper_ret_type(tag, regs).call_arg
+        if ret_type != "void":
+            declared.append(ret_type)
+
+        for arg in hex_common.helper_args(tag, regs, imms):
+            declared.append(arg.call_arg)
 
-        if hex_common.need_pkt_has_multi_cof(tag):
-            f.write(", pkt_has_multi_cof")
-        if hex_common.need_pkt_need_commit(tag):
-            f.write(", pkt_need_commit")
-        if hex_common.need_PC(tag):
-            f.write(", PC")
-        if hex_common.helper_needs_next_PC(tag):
-            f.write(", next_PC")
-        if hex_common.need_slot(tag):
-            f.write(", slotval")
-        if hex_common.need_part1(tag):
-            f.write(", part1")
-        f.write(");\n")
+        arguments = ", ".join(declared)
+        f.write(f"    gen_helper_{tag}({arguments});\n")
 
     ## Write all the outputs
     for regtype, regid in regs:
-        if hex_common.is_written(regid):
-            genptr_dst_write_opn(f, regtype, regid, tag)
+        reg = hex_common.get_register(tag, regtype, regid)
+        if reg.is_written():
+            reg.log_write(f, tag)
 
     f.write("}\n\n")
 
@@ -637,6 +113,7 @@ def main():
     hex_common.read_overrides_file(sys.argv[3])
     hex_common.read_overrides_file(sys.argv[4])
     hex_common.calculate_attribs()
+    hex_common.init_registers()
     ## Whether or not idef-parser is enabled is
     ## determined by the number of arguments to
     ## this script:
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 0da65d6dd6..979f198a30 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -20,12 +20,15 @@
 import sys
 import re
 import string
+import textwrap
 
 behdict = {}  # tag ->behavior
 semdict = {}  # tag -> semantics
 attribdict = {}  # tag -> attributes
 macros = {}  # macro -> macro information...
 attribinfo = {}  # Register information and misc
+registers = {}  # register -> register functions
+new_registers = {}
 tags = []  # list of all tags
 overrides = {}  # tags with helper overrides
 idef_parser_enabled = {}  # tags enabled for idef-parser
@@ -276,6 +279,10 @@ def helper_needs_next_PC(tag):
     return "A_CALL" in attribdict[tag]
 
 
+def need_next_PC(tag):
+    return "A_CALL" in attribdict[tag]
+
+
 def need_pkt_has_multi_cof(tag):
     return "A_COF" in attribdict[tag]
 
@@ -350,3 +357,655 @@ def read_idef_parser_enabled_file(name):
     with open(name, "r") as idef_parser_enabled_file:
         lines = idef_parser_enabled_file.read().strip().split("\n")
         idef_parser_enabled = set(lines)
+
+
+def is_predicated(tag):
+    return "A_CONDEXEC" in attribdict[tag]
+
+
+def code_fmt(txt):
+    return textwrap.indent(textwrap.dedent(txt), "    ")
+
+
+def hvx_newv(tag):
+    if "A_CVI_NEW" in attribdict[tag]:
+        return "EXT_NEW"
+    elif "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]:
+        return "EXT_TMP"
+    else:
+        return "EXT_DFL"
+
+def vreg_offset_func(tag):
+    if "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]:
+        return "ctx_tmp_vreg_off"
+    else:
+        return "ctx_future_vreg_off"
+
+class HelperArg:
+    def __init__(self, proto_arg, call_arg, func_arg):
+        self.proto_arg = proto_arg
+        self.call_arg = call_arg
+        self.func_arg = func_arg
+
+class Register:
+    def __init__(self, regtype, regid):
+        self.regtype = regtype
+        self.regid = regid
+        self.reg_num = f"{regtype}{regid}N"
+    def decl_reg_num(self, f, regno):
+        f.write(code_fmt(f"""\
+            const int {self.reg_num} = insn->regno[{regno}];
+        """))
+    def idef_arg(self, declared):
+        declared.append(self.reg_tcg())
+    def helper_arg(self):
+        return HelperArg(
+            self.helper_proto_type(),
+            self.reg_tcg(),
+            f"{self.helper_arg_type()} {self.helper_arg_name()}"
+        )
+
+#
+# Every register is either Single or Pair or Hvx
+#
+class Scalar:
+    def is_scalar_reg(self):
+        return True
+    def is_hvx_reg(self):
+        return False
+    def helper_arg_name(self):
+        return self.reg_tcg()
+
+class Single(Scalar):
+    def helper_proto_type(self):
+        return "s32"
+    def helper_arg_type(self):
+        return "int32_t"
+
+class Pair(Scalar):
+    def helper_proto_type(self):
+        return "s64"
+    def helper_arg_type(self):
+        return "int64_t"
+
+class Hvx:
+    def is_scalar_reg(self):
+        return False
+    def is_hvx_reg(self):
+        return True
+    def hvx_off(self):
+        return f"{self.reg_tcg()}_off"
+    def helper_proto_type(self):
+        return "ptr"
+    def helper_arg_type(self):
+        return "void *"
+    def helper_arg_name(self):
+        return f"{self.reg_tcg()}_void"
+
+#
+# Every register is either Dest or OldSource or NewSource or ReadWrite
+#
+class Dest:
+    def reg_tcg(self):
+        return f"{self.regtype}{self.regid}V"
+    def is_written(self):
+        return True
+    def is_writeonly(self):
+        return True
+    def is_read(self):
+        return False
+    def is_readwrite(self):
+        return False
+
+class Source:
+    def is_written(self):
+        return False
+    def is_writeonly(self):
+        return False
+    def is_read(self):
+        return True
+    def is_readwrite(self):
+        return False
+
+class OldSource(Source):
+    def reg_tcg(self):
+        return f"{self.regtype}{self.regid}V"
+
+class NewSource(Source):
+    def reg_tcg(self):
+        return f"{self.regtype}{self.regid}N"
+
+class ReadWrite:
+    def reg_tcg(self):
+        return f"{self.regtype}{self.regid}V"
+    def is_written(self):
+        return True
+    def is_writeonly(self):
+        return False
+    def is_read(self):
+        return True
+    def is_readwrite(self):
+        return True
+
+class GprDest(Register, Single, Dest):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class GprSource(Register, Single, OldSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
+        """))
+
+class GprNewSource(Register, Single, NewSource):
+    def decl_tcg(self, f, tag, regno):
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
+        """))
+
+class GprReadWrite(Register, Single, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
+        """))
+        ## For read/write registers, we need to get the original value into
+        ## the result TCGv.  For predicated instructions, this is done in
+        ## gen_start_packet.  For un-predicated instructions, we do it here.
+        if not is_predicated(tag):
+            f.write(code_fmt(f"""\
+                tcg_gen_mov_tl({self.reg_tcg()}, hex_gpr[{self.reg_num}]);
+            """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class ControlDest(Register, Single, Dest):
+    def decl_reg_num(self, f, regno):
+        f.write(code_fmt(f"""\
+            const int {self.reg_num} = insn->regno[{regno}]  + HEX_REG_SA0;
+        """))
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class ControlSource(Register, Single, OldSource):
+    def decl_reg_num(self, f, regno):
+        f.write(code_fmt(f"""\
+            const int {self.reg_num} = insn->regno[{regno}]  + HEX_REG_SA0;
+        """))
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno);
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = tcg_temp_new();
+            gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class ModifierSource(Register, Single, OldSource):
+    def decl_reg_num(self, f, regno):
+        f.write(code_fmt(f"""\
+            const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_M0;
+        """))
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
+            TCGv CS G_GNUC_UNUSED =
+                hex_gpr[{self.reg_num} - HEX_REG_M0 + HEX_REG_CS0];
+        """))
+    def idef_arg(self, declared):
+        declared.append(self.reg_tcg())
+        declared.append("CS")
+
+class PredDest(Register, Single, Dest):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = tcg_temp_new();
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class PredSource(Register, Single, OldSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
+        """))
+
+class PredNewSource(Register, Single, NewSource):
+    def decl_tcg(self, f, tag, regno):
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
+        """))
+
+class PredReadWrite(Register, Single, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv {self.reg_tcg()} = tcg_temp_new();
+            tcg_gen_mov_tl({self.reg_tcg()}, hex_pred[{self.reg_num}]);
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class PairDest(Register, Pair, Dest):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv_i64 {self.reg_tcg()} =
+                get_result_gpr_pair(ctx, {self.reg_num});
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class PairSource(Register, Pair, OldSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
+            tcg_gen_concat_i32_i64({self.reg_tcg()},
+                                    hex_gpr[{self.reg_num}],
+                                    hex_gpr[{self.reg_num} + 1]);
+        """))
+
+class PairReadWrite(Register, Pair, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv_i64 {self.reg_tcg()} =
+                get_result_gpr_pair(ctx, {self.reg_num});
+            tcg_gen_concat_i32_i64({self.reg_tcg()},
+                                   hex_gpr[{self.reg_num}],
+                                   hex_gpr[{self.reg_num} + 1]);
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class ControlPairDest(Register, Pair, Dest):
+    def decl_reg_num(self, f, regno):
+        f.write(code_fmt(f"""\
+            const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
+        """))
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv_i64 {self.reg_tcg()} =
+                get_result_gpr_pair(ctx, {self.reg_num});
+        """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class ControlPairSource(Register, Pair, OldSource):
+    def decl_reg_num(self, f, regno):
+        f.write(code_fmt(f"""\
+            const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
+        """))
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
+            gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
+        """))
+
+class VRegDest(Register, Hvx, Dest):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+    def log_write(self, f, tag):
+        pass
+
+class VRegSource(Register, Hvx, OldSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} = vreg_src_off(ctx, {self.reg_num});
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+
+class VRegNewSource(Register, Hvx, NewSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        if skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                const intptr_t {self.hvx_off()} =
+                    ctx_future_vreg_off(ctx, {self.reg_num}, 1, true);
+            """))
+
+class VRegReadWrite(Register, Hvx, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
+            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
+                             vreg_src_off(ctx, {self.reg_num}),
+                             sizeof(MMVector), sizeof(MMVector));
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+    def log_write(self, f, tag):
+        pass
+
+class VRegTmp(Register, Hvx, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} = offsetof(CPUHexagonState, vtmp);
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+                tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
+                                 vreg_src_off(ctx, {self.reg_num}),
+                                 sizeof(MMVector), sizeof(MMVector));
+            """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
+                               {hvx_newv(tag)});
+        """))
+
+class VRegPairDest(Register, Hvx, Dest):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 2, true);
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+    def log_write(self, f, tag):
+        pass
+
+class VRegPairSource(Register, Hvx, OldSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                offsetof(CPUHexagonState, {self.reg_tcg()});
+            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
+                             vreg_src_off(ctx, {self.reg_num}),
+                             sizeof(MMVector), sizeof(MMVector));
+            tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
+                             vreg_src_off(ctx, {self.reg_num} ^ 1),
+                             sizeof(MMVector), sizeof(MMVector));
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+
+class VRegPairReadWrite(Register, Hvx, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                offsetof(CPUHexagonState, {self.reg_tcg()});
+            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
+                             vreg_src_off(ctx, {self.reg_num}),
+                             sizeof(MMVector), sizeof(MMVector));
+            tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
+                             vreg_src_off(ctx, {self.reg_num} ^ 1),
+                             sizeof(MMVector), sizeof(MMVector));
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+    def log_write(self, f, tag):
+        f.write(code_fmt(f"""\
+            gen_log_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
+                                    {hvx_newv(tag)});
+        """))
+
+class QRegDest(Register, Hvx, Dest):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                get_result_qreg(ctx, {self.reg_num});
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+    def log_write(self, f, tag):
+        pass
+
+class QRegSource(Register, Hvx, OldSource):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                offsetof(CPUHexagonState, QRegs[{self.reg_num}]);
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+
+class QRegReadWrite(Register, Hvx, ReadWrite):
+    def decl_tcg(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            const intptr_t {self.hvx_off()} =
+                get_result_qreg(ctx, {self.reg_num});
+            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
+                             offsetof(CPUHexagonState, QRegs[{self.reg_num}]),
+                             sizeof(MMQReg), sizeof(MMQReg));
+        """))
+        if not skip_qemu_helper(tag):
+            f.write(code_fmt(f"""\
+                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
+                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
+            """))
+    def log_write(self, f, tag):
+        pass
+
+def init_registers():
+    regs = {
+        GprDest("R", "d"),
+        GprDest("R", "e"),
+        GprSource("R", "s"),
+        GprSource("R", "t"),
+        GprSource("R", "u"),
+        GprSource("R", "v"),
+        GprReadWrite("R", "x"),
+        GprReadWrite("R", "y"),
+        ControlDest("C", "d"),
+        ControlSource("C", "s"),
+        ModifierSource("M", "u"),
+        PredDest("P", "d"),
+        PredDest("P", "e"),
+        PredSource("P", "s"),
+        PredSource("P", "t"),
+        PredSource("P", "u"),
+        PredSource("P", "v"),
+        PredReadWrite("P", "x"),
+        PairDest("R", "dd"),
+        PairDest("R", "ee"),
+        PairSource("R", "ss"),
+        PairSource("R", "tt"),
+        PairReadWrite("R", "xx"),
+        PairReadWrite("R", "yy"),
+        ControlPairDest("C", "dd"),
+        ControlPairSource("C", "ss"),
+        VRegDest("V", "d"),
+        VRegSource("V", "s"),
+        VRegSource("V", "u"),
+        VRegSource("V", "v"),
+        VRegSource("V", "w"),
+        VRegReadWrite("V", "x"),
+        VRegTmp("V", "y"),
+        VRegPairDest("V", "dd"),
+        VRegPairSource("V", "uu"),
+        VRegPairSource("V", "vv"),
+        VRegPairReadWrite("V", "xx"),
+        QRegDest("Q", "d"),
+        QRegDest("Q", "e"),
+        QRegSource("Q", "s"),
+        QRegSource("Q", "t"),
+        QRegSource("Q", "u"),
+        QRegSource("Q", "v"),
+        QRegReadWrite("Q", "x"),
+    }
+    for reg in regs:
+        registers[f"{reg.regtype}{reg.regid}"] = reg
+
+    new_regs = {
+        GprNewSource("N", "s"),
+        GprNewSource("N", "t"),
+        PredNewSource("P", "t"),
+        PredNewSource("P", "u"),
+        PredNewSource("P", "v"),
+        VRegNewSource("O", "s"),
+    }
+    for reg in new_regs:
+        new_registers[f"{reg.regtype}{reg.regid}"] = reg
+
+def get_register(tag, regtype, regid):
+    if f"{regtype}{regid}V" in semdict[tag]:
+        return registers[f"{regtype}{regid}"]
+    else:
+        return new_registers[f"{regtype}{regid}"]
+
+def helper_ret_type(tag, regs):
+    ## If there is a scalar result, it is the return type
+    return_type = HelperArg( "void", "void", "void")
+    numscalarresults = 0
+    for regtype, regid in regs:
+        reg = get_register(tag, regtype, regid)
+        if reg.is_written() and reg.is_scalar_reg():
+            return_type = HelperArg(
+                reg.helper_proto_type(),
+                reg.reg_tcg(),
+                reg.helper_arg_type()
+            )
+    if numscalarresults > 1:
+        raise Exception("numscalarresults > 1")
+    return return_type
+
+def helper_args(tag, regs, imms):
+    args = []
+
+    ## First argument is the CPU state
+    args.append(HelperArg(
+        "env",
+        "tcg_env",
+        "CPUHexagonState *env"
+    ))
+
+    ## For predicated instructions, we pass in the destination register
+    if is_predicated(tag):
+        for regtype, regid in regs:
+            reg = get_register(tag, regtype, regid)
+            if reg.is_writeonly() and not reg.is_hvx_reg():
+                args.append(reg.helper_arg())
+
+    ## Pass the HVX destination registers
+    for regtype, regid in regs:
+        reg = get_register(tag, regtype, regid)
+        if reg.is_written() and reg.is_hvx_reg():
+            args.append(reg.helper_arg())
+
+    ## Pass the source registers
+    for regtype, regid in regs:
+        reg = get_register(tag, regtype, regid)
+        if reg.is_read() and not (reg.is_hvx_reg() and reg.is_readwrite()):
+            args.append(reg.helper_arg())
+
+    ## Pass the immediates
+    for immlett, bits, immshift in imms:
+        args.append(HelperArg(
+            "s32",
+            f"tcg_constant_tl({imm_name(immlett)})",
+            f"int32_t {imm_name(immlett)}"
+        ))
+
+    ## Other stuff the helper might need
+    if need_pkt_has_multi_cof(tag):
+        args.append(HelperArg(
+            "i32",
+            "tcg_constant_tl(ctx->pkt->pkt_has_multi_cof)",
+            "uint32_t pkt_has_multi_cof"
+        ))
+    if need_pkt_need_commit(tag):
+        args.append(HelperArg(
+            "i32",
+            "tcg_constant_tl(ctx->need_commit)",
+            "uint32_t pkt_need_commit"
+        ))
+    if need_PC(tag):
+        args.append(HelperArg(
+            "i32",
+            "tcg_constant_tl(ctx->pkt->pc)",
+            "target_ulong PC"
+        ))
+    if need_next_PC(tag):
+        args.append(HelperArg(
+            "i32",
+            "tcg_constant_tl(ctx->next_PC)",
+            "target_ulong next_PC"
+        ))
+    if need_slot(tag):
+        args.append(HelperArg(
+            "i32",
+            "gen_slotval(ctx)",
+            "uint32_t slotval"
+        ))
+    if need_part1(tag):
+        args.append(HelperArg(
+            "i32",
+            "tcg_constant_tl(insn->part1)"
+            "uint32_t part1"
+        ))
+    return args
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
  2023-12-10 22:07 ` [PATCH v2 1/9] Hexagon (target/hexagon) Clean up handling of modifier registers Taylor Simpson
  2023-12-10 22:07 ` [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:08   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs Taylor Simpson
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_helper_protos.py | 149 ++--------------------------
 target/hexagon/hex_common.py        |   7 --
 2 files changed, 8 insertions(+), 148 deletions(-)

diff --git a/target/hexagon/gen_helper_protos.py b/target/hexagon/gen_helper_protos.py
index 131043795a..c82b0f54e4 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -22,39 +22,6 @@
 import string
 import hex_common
 
-##
-## Helpers for gen_helper_prototype
-##
-def_helper_types = {
-    "N": "s32",
-    "O": "s32",
-    "P": "s32",
-    "M": "s32",
-    "C": "s32",
-    "R": "s32",
-    "V": "ptr",
-    "Q": "ptr",
-}
-
-def_helper_types_pair = {
-    "R": "s64",
-    "C": "s64",
-    "S": "s64",
-    "G": "s64",
-    "V": "ptr",
-    "Q": "ptr",
-}
-
-
-def gen_def_helper_opn(f, tag, regtype, regid, i):
-    if hex_common.is_pair(regid):
-        f.write(f", {def_helper_types_pair[regtype]}")
-    elif hex_common.is_single(regid):
-        f.write(f", {def_helper_types[regtype]}")
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
 ##
 ## Generate the DEF_HELPER prototype for an instruction
 ##     For A2_add: Rd32=add(Rs32,Rt32)
@@ -65,116 +32,15 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
     regs = tagregs[tag]
     imms = tagimms[tag]
 
-    numresults = 0
-    numscalarresults = 0
-    numscalarreadwrite = 0
-    for regtype, regid in regs:
-        if hex_common.is_written(regid):
-            numresults += 1
-            if hex_common.is_scalar_reg(regtype):
-                numscalarresults += 1
-        if hex_common.is_readwrite(regid):
-            if hex_common.is_scalar_reg(regtype):
-                numscalarreadwrite += 1
-
-    if numscalarresults > 1:
-        ## The helper is bogus when there is more than one result
-        f.write(f"DEF_HELPER_1({tag}, void, env)\n")
-    else:
-        ## Figure out how many arguments the helper will take
-        if numscalarresults == 0:
-            def_helper_size = len(regs) + len(imms) + numscalarreadwrite + 1
-            if hex_common.need_pkt_has_multi_cof(tag):
-                def_helper_size += 1
-            if hex_common.need_pkt_need_commit(tag):
-                def_helper_size += 1
-            if hex_common.need_part1(tag):
-                def_helper_size += 1
-            if hex_common.need_slot(tag):
-                def_helper_size += 1
-            if hex_common.need_PC(tag):
-                def_helper_size += 1
-            if hex_common.helper_needs_next_PC(tag):
-                def_helper_size += 1
-            if hex_common.need_condexec_reg(tag, regs):
-                def_helper_size += 1
-            f.write(f"DEF_HELPER_{def_helper_size}({tag}")
-            ## The return type is void
-            f.write(", void")
-        else:
-            def_helper_size = len(regs) + len(imms) + numscalarreadwrite
-            if hex_common.need_pkt_has_multi_cof(tag):
-                def_helper_size += 1
-            if hex_common.need_pkt_need_commit(tag):
-                def_helper_size += 1
-            if hex_common.need_part1(tag):
-                def_helper_size += 1
-            if hex_common.need_slot(tag):
-                def_helper_size += 1
-            if hex_common.need_PC(tag):
-                def_helper_size += 1
-            if hex_common.need_condexec_reg(tag, regs):
-                def_helper_size += 1
-            if hex_common.helper_needs_next_PC(tag):
-                def_helper_size += 1
-            f.write(f"DEF_HELPER_{def_helper_size}({tag}")
-
-        ## Generate the qemu DEF_HELPER type for each result
-        ## Iterate over this list twice
-        ## - Emit the scalar result
-        ## - Emit the vector result
-        i = 0
-        for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                if not hex_common.is_hvx_reg(regtype):
-                    gen_def_helper_opn(f, tag, regtype, regid, i)
-                i += 1
-
-        ## Put the env between the outputs and inputs
-        f.write(", env")
-        i += 1
-
-        # Second pass
-        for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                if hex_common.is_hvx_reg(regtype):
-                    gen_def_helper_opn(f, tag, regtype, regid, i)
-                    i += 1
-
-        ## For conditional instructions, we pass in the destination register
-        if "A_CONDEXEC" in hex_common.attribdict[tag]:
-            for regtype, regid in regs:
-                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
-                    regtype
-                ):
-                    gen_def_helper_opn(f, tag, regtype, regid, i)
-                    i += 1
+    declared = []
+    ret_type = hex_common.helper_ret_type(tag, regs).proto_arg
+    declared.append(ret_type)
 
-        ## Generate the qemu type for each input operand (regs and immediates)
-        for regtype, regid in regs:
-            if hex_common.is_read(regid):
-                if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
-                    continue
-                gen_def_helper_opn(f, tag, regtype, regid, i)
-                i += 1
-        for immlett, bits, immshift in imms:
-            f.write(", s32")
+    for arg in hex_common.helper_args(tag, regs, imms):
+        declared.append(arg.proto_arg)
 
-        ## Add the arguments for the instruction pkt_has_multi_cof,
-        ## pkt_needs_commit, PC, next_PC, slot, and part1 (if needed)
-        if hex_common.need_pkt_has_multi_cof(tag):
-            f.write(", i32")
-        if hex_common.need_pkt_need_commit(tag):
-            f.write(', i32')
-        if hex_common.need_PC(tag):
-            f.write(", i32")
-        if hex_common.helper_needs_next_PC(tag):
-            f.write(", i32")
-        if hex_common.need_slot(tag):
-            f.write(", i32")
-        if hex_common.need_part1(tag):
-            f.write(" , i32")
-        f.write(")\n")
+    arguments = ", ".join(declared)
+    f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
 
 
 def main():
@@ -195,6 +61,7 @@ def main():
     if is_idef_parser_enabled:
         hex_common.read_idef_parser_enabled_file(sys.argv[5])
     hex_common.calculate_attribs()
+    hex_common.init_registers()
     tagregs = hex_common.get_tagregs()
     tagimms = hex_common.get_tagimms()
 
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 979f198a30..2abd653e6d 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -290,13 +290,6 @@ def need_pkt_has_multi_cof(tag):
 def need_pkt_need_commit(tag):
     return 'A_IMPLICIT_WRITES_USR' in attribdict[tag]
 
-def need_condexec_reg(tag, regs):
-    if "A_CONDEXEC" in attribdict[tag]:
-        for regtype, regid in regs:
-            if is_writeonly(regid) and not is_hvx_reg(regtype):
-                return True
-    return False
-
 
 def skip_qemu_helper(tag):
     return tag in overrides.keys()
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (2 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:09   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs Taylor Simpson
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_helper_funcs.py | 368 +++++------------------------
 target/hexagon/hex_common.py       |  48 +++-
 2 files changed, 103 insertions(+), 313 deletions(-)

diff --git a/target/hexagon/gen_helper_funcs.py b/target/hexagon/gen_helper_funcs.py
index ce21d3b688..9cc3d69c49 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -23,181 +23,14 @@
 import hex_common
 
 
-##
-## Helpers for gen_helper_function
-##
-def gen_decl_ea(f):
-    f.write("    uint32_t EA;\n")
-
-
-def gen_helper_return_type(f, regtype, regid, regno):
-    if regno > 1:
-        f.write(", ")
-    f.write("int32_t")
-
-
-def gen_helper_return_type_pair(f, regtype, regid, regno):
-    if regno > 1:
-        f.write(", ")
-    f.write("int64_t")
-
-
-def gen_helper_arg(f, regtype, regid, regno):
-    if regno > 0:
-        f.write(", ")
-    f.write(f"int32_t {regtype}{regid}V")
-
-
-def gen_helper_arg_new(f, regtype, regid, regno):
-    if regno >= 0:
-        f.write(", ")
-    f.write(f"int32_t {regtype}{regid}N")
-
-
-def gen_helper_arg_pair(f, regtype, regid, regno):
-    if regno >= 0:
-        f.write(", ")
-    f.write(f"int64_t {regtype}{regid}V")
-
-
-def gen_helper_arg_ext(f, regtype, regid, regno):
-    if regno > 0:
-        f.write(", ")
-    f.write(f"void *{regtype}{regid}V_void")
-
-
-def gen_helper_arg_ext_pair(f, regtype, regid, regno):
-    if regno > 0:
-        f.write(", ")
-    f.write(f"void *{regtype}{regid}V_void")
-
-
-def gen_helper_arg_opn(f, regtype, regid, i, tag):
-    if hex_common.is_pair(regid):
-        if hex_common.is_hvx_reg(regtype):
-            gen_helper_arg_ext_pair(f, regtype, regid, i)
-        else:
-            gen_helper_arg_pair(f, regtype, regid, i)
-    elif hex_common.is_single(regid):
-        if hex_common.is_old_val(regtype, regid, tag):
-            if hex_common.is_hvx_reg(regtype):
-                gen_helper_arg_ext(f, regtype, regid, i)
-            else:
-                gen_helper_arg(f, regtype, regid, i)
-        elif hex_common.is_new_val(regtype, regid, tag):
-            gen_helper_arg_new(f, regtype, regid, i)
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def gen_helper_arg_imm(f, immlett):
-    f.write(f", int32_t {hex_common.imm_name(immlett)}")
-
-
-def gen_helper_dest_decl(f, regtype, regid, regno, subfield=""):
-    f.write(f"    int32_t {regtype}{regid}V{subfield} = 0;\n")
-
-
-def gen_helper_dest_decl_pair(f, regtype, regid, regno, subfield=""):
-    f.write(f"    int64_t {regtype}{regid}V{subfield} = 0;\n")
-
-
-def gen_helper_dest_decl_ext(f, regtype, regid):
-    if regtype == "Q":
-        f.write(
-            f"    /* {regtype}{regid}V is *(MMQReg *)" f"({regtype}{regid}V_void) */\n"
-        )
-    else:
-        f.write(
-            f"    /* {regtype}{regid}V is *(MMVector *)"
-            f"({regtype}{regid}V_void) */\n"
-        )
-
-
-def gen_helper_dest_decl_ext_pair(f, regtype, regid, regno):
-    f.write(
-        f"    /* {regtype}{regid}V is *(MMVectorPair *))"
-        f"{regtype}{regid}V_void) */\n"
-    )
-
-
-def gen_helper_dest_decl_opn(f, regtype, regid, i):
-    if hex_common.is_pair(regid):
-        if hex_common.is_hvx_reg(regtype):
-            gen_helper_dest_decl_ext_pair(f, regtype, regid, i)
-        else:
-            gen_helper_dest_decl_pair(f, regtype, regid, i)
-    elif hex_common.is_single(regid):
-        if hex_common.is_hvx_reg(regtype):
-            gen_helper_dest_decl_ext(f, regtype, regid)
-        else:
-            gen_helper_dest_decl(f, regtype, regid, i)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def gen_helper_src_var_ext(f, regtype, regid):
-    if regtype == "Q":
-        f.write(
-            f"    /* {regtype}{regid}V is *(MMQReg *)" f"({regtype}{regid}V_void) */\n"
-        )
-    else:
-        f.write(
-            f"    /* {regtype}{regid}V is *(MMVector *)"
-            f"({regtype}{regid}V_void) */\n"
-        )
-
-
-def gen_helper_src_var_ext_pair(f, regtype, regid, regno):
-    f.write(
-        f"    /* {regtype}{regid}V{regno} is *(MMVectorPair *)"
-        f"({regtype}{regid}V{regno}_void) */\n"
-    )
-
-
-def gen_helper_return(f, regtype, regid, regno):
-    f.write(f"    return {regtype}{regid}V;\n")
-
-
-def gen_helper_return_pair(f, regtype, regid, regno):
-    f.write(f"    return {regtype}{regid}V;\n")
-
-
-def gen_helper_dst_write_ext(f, regtype, regid):
-    return
-
-
-def gen_helper_dst_write_ext_pair(f, regtype, regid):
-    return
-
-
-def gen_helper_return_opn(f, regtype, regid, i):
-    if hex_common.is_pair(regid):
-        if hex_common.is_hvx_reg(regtype):
-            gen_helper_dst_write_ext_pair(f, regtype, regid)
-        else:
-            gen_helper_return_pair(f, regtype, regid, i)
-    elif hex_common.is_single(regid):
-        if hex_common.is_hvx_reg(regtype):
-            gen_helper_dst_write_ext(f, regtype, regid)
-        else:
-            gen_helper_return(f, regtype, regid, i)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
 ##
 ## Generate the TCG code to call the helper
 ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
 ##     We produce:
 ##       int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t RtV)
 ##       {
-##           uint32_t slot __attribute__(unused)) = 4;
 ##           int32_t RdV = 0;
 ##           { RdV=RsV+RtV;}
-##           COUNT_HELPER(A2_add);
 ##           return RdV;
 ##       }
 ##
@@ -205,151 +38,67 @@ def gen_helper_function(f, tag, tagregs, tagimms):
     regs = tagregs[tag]
     imms = tagimms[tag]
 
-    numresults = 0
-    numscalarresults = 0
-    numscalarreadwrite = 0
-    for regtype, regid in regs:
-        if hex_common.is_written(regid):
-            numresults += 1
-            if hex_common.is_scalar_reg(regtype):
-                numscalarresults += 1
-        if hex_common.is_readwrite(regid):
-            if hex_common.is_scalar_reg(regtype):
-                numscalarreadwrite += 1
-
-    if numscalarresults > 1:
-        ## The helper is bogus when there is more than one result
-        f.write(
-            f"void HELPER({tag})(CPUHexagonState *env) " f"{{ BOGUS_HELPER({tag}); }}\n"
-        )
-    else:
-        ## The return type of the function is the type of the destination
-        ## register (if scalar)
-        i = 0
+    ret_type = hex_common.helper_ret_type(tag, regs).func_arg
+
+    declared = []
+    for arg in hex_common.helper_args(tag, regs, imms):
+        declared.append(arg.func_arg)
+
+    arguments = ", ".join(declared)
+    f.write(f"{ret_type} HELPER({tag})({arguments})\n")
+    f.write("{\n")
+    if hex_common.need_ea(tag):
+        f.write(hex_common.code_fmt(f"""\
+            uint32_t EA;
+        """))
+    ## Declare the return variable
+    if not hex_common.is_predicated(tag):
         for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                if hex_common.is_pair(regid):
-                    if hex_common.is_hvx_reg(regtype):
-                        continue
-                    else:
-                        gen_helper_return_type_pair(f, regtype, regid, i)
-                elif hex_common.is_single(regid):
-                    if hex_common.is_hvx_reg(regtype):
-                        continue
-                    else:
-                        gen_helper_return_type(f, regtype, regid, i)
-                else:
-                    hex_common.bad_register(regtype, regid)
-            i += 1
+            reg = hex_common.get_register(tag, regtype, regid)
+            if reg.is_writeonly() and not reg.is_hvx_reg():
+                f.write(hex_common.code_fmt(f"""\
+                    {reg.helper_arg_type()} {reg.helper_arg_name()} = 0;
+                """))
 
-        if numscalarresults == 0:
-            f.write("void")
-        f.write(f" HELPER({tag})(CPUHexagonState *env")
-
-        ## Arguments include the vector destination operands
-        i = 1
-        for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                if hex_common.is_pair(regid):
-                    if hex_common.is_hvx_reg(regtype):
-                        gen_helper_arg_ext_pair(f, regtype, regid, i)
-                    else:
-                        continue
-                elif hex_common.is_single(regid):
-                    if hex_common.is_hvx_reg(regtype):
-                        gen_helper_arg_ext(f, regtype, regid, i)
-                    else:
-                        # This is the return value of the function
-                        continue
-                else:
-                    hex_common.bad_register(regtype, regid)
-                i += 1
-
-        ## For conditional instructions, we pass in the destination register
-        if "A_CONDEXEC" in hex_common.attribdict[tag]:
-            for regtype, regid in regs:
-                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
-                    regtype
-                ):
-                    gen_helper_arg_opn(f, regtype, regid, i, tag)
-                    i += 1
-
-        ## Arguments to the helper function are the source regs and immediates
-        for regtype, regid in regs:
-            if hex_common.is_read(regid):
-                if hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid):
-                    continue
-                gen_helper_arg_opn(f, regtype, regid, i, tag)
-                i += 1
-        for immlett, bits, immshift in imms:
-            gen_helper_arg_imm(f, immlett)
-            i += 1
-
-        if hex_common.need_pkt_has_multi_cof(tag):
-            f.write(", uint32_t pkt_has_multi_cof")
-        if (hex_common.need_pkt_need_commit(tag)):
-            f.write(", uint32_t pkt_need_commit")
-
-        if hex_common.need_PC(tag):
-            if i > 0:
-                f.write(", ")
-            f.write("target_ulong PC")
-            i += 1
-        if hex_common.helper_needs_next_PC(tag):
-            if i > 0:
-                f.write(", ")
-            f.write("target_ulong next_PC")
-            i += 1
-        if hex_common.need_slot(tag):
-            if i > 0:
-                f.write(", ")
-            f.write("uint32_t slotval")
-            i += 1
-        if hex_common.need_part1(tag):
-            if i > 0:
-                f.write(", ")
-            f.write("uint32_t part1")
-        f.write(")\n{\n")
-        if hex_common.need_ea(tag):
-            gen_decl_ea(f)
-        ## Declare the return variable
-        i = 0
-        if "A_CONDEXEC" not in hex_common.attribdict[tag]:
-            for regtype, regid in regs:
-                if hex_common.is_writeonly(regid):
-                    gen_helper_dest_decl_opn(f, regtype, regid, i)
-                i += 1
-
-        for regtype, regid in regs:
-            if hex_common.is_read(regid):
-                if hex_common.is_pair(regid):
-                    if hex_common.is_hvx_reg(regtype):
-                        gen_helper_src_var_ext_pair(f, regtype, regid, i)
-                elif hex_common.is_single(regid):
-                    if hex_common.is_hvx_reg(regtype):
-                        gen_helper_src_var_ext(f, regtype, regid)
-                else:
-                    hex_common.bad_register(regtype, regid)
-
-        if hex_common.need_slot(tag):
-            if "A_LOAD" in hex_common.attribdict[tag]:
-                f.write("    bool pkt_has_store_s1 = slotval & 0x1;\n")
-            f.write("    uint32_t slot = slotval >> 1;\n")
-
-        if "A_FPOP" in hex_common.attribdict[tag]:
-            f.write("    arch_fpop_start(env);\n")
-
-        f.write(f"    {hex_common.semdict[tag]}\n")
-
-        if "A_FPOP" in hex_common.attribdict[tag]:
-            f.write("    arch_fpop_end(env);\n")
+    ## Print useful information about HVX registers
+    for regtype, regid in regs:
+        reg = hex_common.get_register(tag, regtype, regid)
+        if reg.is_hvx_reg():
+            reg.helper_hvx_desc(f)
+
+    if hex_common.need_slot(tag):
+        if "A_LOAD" in hex_common.attribdict[tag]:
+            f.write(hex_common.code_fmt(f"""\
+                bool pkt_has_store_s1 = slotval & 0x1;
+            """))
+        f.write(hex_common.code_fmt(f"""\
+            uint32_t slot = slotval >> 1;
+        """))
+
+    if "A_FPOP" in hex_common.attribdict[tag]:
+        f.write(hex_common.code_fmt(f"""\
+            arch_fpop_start(env);
+        """))
+
+    f.write(hex_common.code_fmt(f"""\
+        {hex_common.semdict[tag]}
+    """))
+
+    if "A_FPOP" in hex_common.attribdict[tag]:
+        f.write(hex_common.code_fmt(f"""\
+            arch_fpop_end(env);
+        """))
+
+    ## Return the scalar result
+    for regtype, regid in regs:
+        reg = hex_common.get_register(tag, regtype, regid)
+        if reg.is_written() and not reg.is_hvx_reg():
+            f.write(hex_common.code_fmt(f"""\
+                return {reg.helper_arg_name()};
+            """))
 
-        ## Save/return the return variable
-        for regtype, regid in regs:
-            if hex_common.is_written(regid):
-                gen_helper_return_opn(f, regtype, regid, i)
-        f.write("}\n\n")
-        ## End of the helper definition
+    f.write("}\n\n")
+    ## End of the helper definition
 
 
 def main():
@@ -370,6 +119,7 @@ def main():
     if is_idef_parser_enabled:
         hex_common.read_idef_parser_enabled_file(sys.argv[5])
     hex_common.calculate_attribs()
+    hex_common.init_registers()
     tagregs = hex_common.get_tagregs()
     tagimms = hex_common.get_tagimms()
 
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 2abd653e6d..fc9ce4e2b0 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -275,10 +275,6 @@ def need_PC(tag):
     return "A_IMPLICIT_READS_PC" in attribdict[tag]
 
 
-def helper_needs_next_PC(tag):
-    return "A_CALL" in attribdict[tag]
-
-
 def need_next_PC(tag):
     return "A_CALL" in attribdict[tag]
 
@@ -680,6 +676,10 @@ def decl_tcg(self, f, tag, regno):
             """))
     def log_write(self, f, tag):
         pass
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
+        """))
 
 class VRegSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -692,6 +692,10 @@ 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 helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
+        """))
 
 class VRegNewSource(Register, Hvx, NewSource):
     def decl_tcg(self, f, tag, regno):
@@ -701,6 +705,10 @@ def decl_tcg(self, f, tag, regno):
                 const intptr_t {self.hvx_off()} =
                     ctx_future_vreg_off(ctx, {self.reg_num}, 1, true);
             """))
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
+        """))
 
 class VRegReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -719,6 +727,10 @@ def decl_tcg(self, f, tag, regno):
             """))
     def log_write(self, f, tag):
         pass
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
+        """))
 
 class VRegTmp(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -739,6 +751,10 @@ def log_write(self, f, tag):
             gen_log_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
                                {hvx_newv(tag)});
         """))
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
+        """))
 
 class VRegPairDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -754,6 +770,10 @@ def decl_tcg(self, f, tag, regno):
             """))
     def log_write(self, f, tag):
         pass
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
+        """))
 
 class VRegPairSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -773,6 +793,10 @@ 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 helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
+        """))
 
 class VRegPairReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -797,6 +821,10 @@ def log_write(self, f, tag):
             gen_log_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
                                     {hvx_newv(tag)});
         """))
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
+        """))
 
 class QRegDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -812,6 +840,10 @@ def decl_tcg(self, f, tag, regno):
             """))
     def log_write(self, f, tag):
         pass
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
+        """))
 
 class QRegSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -825,6 +857,10 @@ 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 helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
+        """))
 
 class QRegReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -843,6 +879,10 @@ def decl_tcg(self, f, tag, regno):
             """))
     def log_write(self, f, tag):
         pass
+    def helper_hvx_desc(self, f):
+        f.write(code_fmt(f"""\
+            /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
+        """))
 
 def init_registers():
     regs = {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (3 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:08   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs Taylor Simpson
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_idef_parser_funcs.py | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/target/hexagon/gen_idef_parser_funcs.py b/target/hexagon/gen_idef_parser_funcs.py
index f4518e653f..550a48cb7b 100644
--- a/target/hexagon/gen_idef_parser_funcs.py
+++ b/target/hexagon/gen_idef_parser_funcs.py
@@ -46,6 +46,7 @@ def main():
     hex_common.read_semantics_file(sys.argv[1])
     hex_common.read_attribs_file(sys.argv[2])
     hex_common.calculate_attribs()
+    hex_common.init_registers()
     tagregs = hex_common.get_tagregs()
     tagimms = hex_common.get_tagimms()
 
@@ -132,22 +133,9 @@ def main():
 
             arguments = []
             for regtype, regid in regs:
-                prefix = "in " if hex_common.is_read(regid) else ""
-
-                is_pair = hex_common.is_pair(regid)
-                is_single_old = hex_common.is_single(regid) and hex_common.is_old_val(
-                    regtype, regid, tag
-                )
-                is_single_new = hex_common.is_single(regid) and hex_common.is_new_val(
-                    regtype, regid, tag
-                )
-
-                if is_pair or is_single_old:
-                    arguments.append(f"{prefix}{regtype}{regid}V")
-                elif is_single_new:
-                    arguments.append(f"{prefix}{regtype}{regid}N")
-                else:
-                    hex_common.bad_register(regtype, regid)
+                reg = hex_common.get_register(tag, regtype, regid)
+                prefix = "in " if reg.is_read() else ""
+                arguments.append(f"{prefix}{reg.reg_tcg()}")
 
             for immlett, bits, immshift in imms:
                 arguments.append(hex_common.imm_name(immlett))
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (4 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:09   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs Taylor Simpson
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

Reviewed-by: Brian Cain <bcain@quicinc.com>
Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_op_regs.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/gen_op_regs.py b/target/hexagon/gen_op_regs.py
index a8a7712129..7b7b33895a 100755
--- a/target/hexagon/gen_op_regs.py
+++ b/target/hexagon/gen_op_regs.py
@@ -70,6 +70,7 @@ def strip_reg_prefix(x):
 def main():
     hex_common.read_semantics_file(sys.argv[1])
     hex_common.read_attribs_file(sys.argv[2])
+    hex_common.init_registers()
     tagregs = hex_common.get_tagregs(full=True)
     tagimms = hex_common.get_tagimms()
 
@@ -80,11 +81,12 @@ def main():
             wregs = []
             regids = ""
             for regtype, regid, _, numregs in regs:
-                if hex_common.is_read(regid):
+                reg = hex_common.get_register(tag, regtype, regid)
+                if reg.is_read():
                     if regid[0] not in regids:
                         regids += regid[0]
                     rregs.append(regtype + regid + numregs)
-                if hex_common.is_written(regid):
+                if reg.is_written():
                     wregs.append(regtype + regid + numregs)
                     if regid[0] not in regids:
                         regids += regid[0]
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (5 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:09   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute Taylor Simpson
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

This patch conflicts with
https://lists.gnu.org/archive/html/qemu-devel/2023-11/msg00729.html
If that series goes in first, we'll rework this patch and vice versa.

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/gen_analyze_funcs.py | 163 +---------------------------
 target/hexagon/hex_common.py        | 151 ++++++++++++++++++++++++++
 2 files changed, 157 insertions(+), 157 deletions(-)

diff --git a/target/hexagon/gen_analyze_funcs.py b/target/hexagon/gen_analyze_funcs.py
index c3b521abef..a9af666cef 100755
--- a/target/hexagon/gen_analyze_funcs.py
+++ b/target/hexagon/gen_analyze_funcs.py
@@ -23,162 +23,6 @@
 import hex_common
 
 
-##
-## Helpers for gen_analyze_func
-##
-def is_predicated(tag):
-    return "A_CONDEXEC" in hex_common.attribdict[tag]
-
-
-def analyze_opn_old(f, tag, regtype, regid, regno):
-    regN = f"{regtype}{regid}N"
-    predicated = "true" if is_predicated(tag) else "false"
-    if regtype == "R":
-        if regid in {"ss", "tt"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_reg_read_pair(ctx, {regN});\n")
-        elif regid in {"dd", "ee", "xx", "yy"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n")
-        elif regid in {"s", "t", "u", "v"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
-        elif regid in {"d", "e", "x", "y"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_reg_write(ctx, {regN}, {predicated});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid in {"s", "t", "u", "v"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_pred_read(ctx, {regN});\n")
-        elif regid in {"d", "e", "x"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_pred_write(ctx, {regN});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "C":
-        if regid == "ss":
-            f.write(
-                f"    const int {regN} = insn->regno[{regno}] "
-                "+ HEX_REG_SA0;\n"
-            )
-            f.write(f"    ctx_log_reg_read_pair(ctx, {regN});\n")
-        elif regid == "dd":
-            f.write(f"    const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n")
-            f.write(f"    ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n")
-        elif regid == "s":
-            f.write(
-                f"    const int {regN} = insn->regno[{regno}] "
-                "+ HEX_REG_SA0;\n"
-            )
-            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
-        elif regid == "d":
-            f.write(f"    const int {regN} = insn->regno[{regno}] " "+ HEX_REG_SA0;\n")
-            f.write(f"    ctx_log_reg_write(ctx, {regN}, {predicated});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "M":
-        if regid == "u":
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "V":
-        newv = "EXT_DFL"
-        if hex_common.is_new_result(tag):
-            newv = "EXT_NEW"
-        elif hex_common.is_tmp_result(tag):
-            newv = "EXT_TMP"
-        if regid in {"dd", "xx"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(
-                f"    ctx_log_vreg_write_pair(ctx, {regN}, {newv}, " f"{predicated});\n"
-            )
-        elif regid in {"uu", "vv"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_vreg_read_pair(ctx, {regN});\n")
-        elif regid in {"s", "u", "v", "w"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_vreg_read(ctx, {regN});\n")
-        elif regid in {"d", "x", "y"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_vreg_write(ctx, {regN}, {newv}, " f"{predicated});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "Q":
-        if regid in {"d", "e", "x"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_qreg_write(ctx, {regN});\n")
-        elif regid in {"s", "t", "u", "v"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_qreg_read(ctx, {regN});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "G":
-        if regid in {"dd"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"d"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"ss"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"s"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "S":
-        if regid in {"dd"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"d"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"ss"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        elif regid in {"s"}:
-            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def analyze_opn_new(f, tag, regtype, regid, regno):
-    regN = f"{regtype}{regid}N"
-    if regtype == "N":
-        if regid in {"s", "t"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "P":
-        if regid in {"t", "u", "v"}:
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_pred_read(ctx, {regN});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    elif regtype == "O":
-        if regid == "s":
-            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
-            f.write(f"    ctx_log_vreg_read(ctx, {regN});\n")
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
-def analyze_opn(f, tag, regtype, regid, i):
-    if hex_common.is_pair(regid):
-        analyze_opn_old(f, tag, regtype, regid, i)
-    elif hex_common.is_single(regid):
-        if hex_common.is_old_val(regtype, regid, tag):
-            analyze_opn_old(f, tag, regtype, regid, i)
-        elif hex_common.is_new_val(regtype, regid, tag):
-            analyze_opn_new(f, tag, regtype, regid, i)
-        else:
-            hex_common.bad_register(regtype, regid)
-    else:
-        hex_common.bad_register(regtype, regid)
-
-
 ##
 ## Generate the code to analyze the instruction
 ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
@@ -203,7 +47,11 @@ def gen_analyze_func(f, tag, regs, imms):
     i = 0
     ## Analyze all the registers
     for regtype, regid in regs:
-        analyze_opn(f, tag, regtype, regid, i)
+        reg = hex_common.get_register(tag, regtype, regid)
+        if reg.is_written():
+            reg.analyze_write(f, tag, i)
+        else:
+            reg.analyze_read(f, i)
         i += 1
 
     has_generated_helper = not hex_common.skip_qemu_helper(
@@ -236,6 +84,7 @@ def main():
     if is_idef_parser_enabled:
         hex_common.read_idef_parser_enabled_file(sys.argv[5])
     hex_common.calculate_attribs()
+    hex_common.init_registers()
     tagregs = hex_common.get_tagregs()
     tagimms = hex_common.get_tagimms()
 
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index fc9ce4e2b0..4565dd1953 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -486,6 +486,12 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
+        """))
 
 class GprSource(Register, Single, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -493,12 +499,22 @@ def decl_tcg(self, f, tag, regno):
         f.write(code_fmt(f"""\
             TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_reg_read(ctx, {self.reg_num});
+        """))
 
 class GprNewSource(Register, Single, NewSource):
     def decl_tcg(self, f, tag, regno):
         f.write(code_fmt(f"""\
             TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_reg_read(ctx, {self.reg_num});
+        """))
 
 class GprReadWrite(Register, Single, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -517,6 +533,12 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
+        """))
 
 class ControlDest(Register, Single, Dest):
     def decl_reg_num(self, f, regno):
@@ -532,6 +554,12 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
+        """))
 
 class ControlSource(Register, Single, OldSource):
     def decl_reg_num(self, f, regno):
@@ -544,6 +572,11 @@ def decl_tcg(self, f, tag, regno):
             TCGv {self.reg_tcg()} = tcg_temp_new();
             gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_reg_read(ctx, {self.reg_num});
+        """))
 
 class ModifierSource(Register, Single, OldSource):
     def decl_reg_num(self, f, regno):
@@ -560,6 +593,11 @@ def decl_tcg(self, f, tag, regno):
     def idef_arg(self, declared):
         declared.append(self.reg_tcg())
         declared.append("CS")
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_reg_read(ctx, {self.reg_num});
+        """))
 
 class PredDest(Register, Single, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -571,6 +609,11 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_pred_write(ctx, {self.reg_num});
+        """))
 
 class PredSource(Register, Single, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -578,12 +621,22 @@ def decl_tcg(self, f, tag, regno):
         f.write(code_fmt(f"""\
             TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_pred_read(ctx, {self.reg_num});
+        """))
 
 class PredNewSource(Register, Single, NewSource):
     def decl_tcg(self, f, tag, regno):
         f.write(code_fmt(f"""\
             TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_pred_read(ctx, {self.reg_num});
+        """))
 
 class PredReadWrite(Register, Single, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -596,6 +649,11 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_pred_write(ctx, {self.reg_num});
+        """))
 
 class PairDest(Register, Pair, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -608,6 +666,12 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
+        """))
 
 class PairSource(Register, Pair, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -618,6 +682,11 @@ def decl_tcg(self, f, tag, regno):
                                     hex_gpr[{self.reg_num}],
                                     hex_gpr[{self.reg_num} + 1]);
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_reg_read_pair(ctx, {self.reg_num});
+        """))
 
 class PairReadWrite(Register, Pair, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -633,6 +702,12 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
+        """))
 
 class ControlPairDest(Register, Pair, Dest):
     def decl_reg_num(self, f, regno):
@@ -649,6 +724,12 @@ def log_write(self, f, tag):
         f.write(code_fmt(f"""\
             gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
+        """))
 
 class ControlPairSource(Register, Pair, OldSource):
     def decl_reg_num(self, f, regno):
@@ -661,6 +742,11 @@ def decl_tcg(self, f, tag, regno):
             TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
             gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_reg_read_pair(ctx, {self.reg_num});
+        """))
 
 class VRegDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -680,6 +766,13 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        newv = hvx_newv(tag)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+        """))
 
 class VRegSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -696,6 +789,11 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_read(ctx, {self.reg_num});
+        """))
 
 class VRegNewSource(Register, Hvx, NewSource):
     def decl_tcg(self, f, tag, regno):
@@ -709,6 +807,11 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_read(ctx, {self.reg_num});
+        """))
 
 class VRegReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -731,6 +834,13 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        newv = hvx_newv(tag)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+        """))
 
 class VRegTmp(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -755,6 +865,13 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        newv = hvx_newv(tag)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+        """))
 
 class VRegPairDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -774,6 +891,13 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        newv = hvx_newv(tag)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
+        """))
 
 class VRegPairSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -797,6 +921,11 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_read_pair(ctx, {self.reg_num});
+        """))
 
 class VRegPairReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -825,6 +954,13 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        newv = hvx_newv(tag)
+        predicated = "true" if is_predicated(tag) else "false"
+        f.write(code_fmt(f"""\
+            ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
+        """))
 
 class QRegDest(Register, Hvx, Dest):
     def decl_tcg(self, f, tag, regno):
@@ -844,6 +980,11 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_qreg_write(ctx, {self.reg_num});
+        """))
 
 class QRegSource(Register, Hvx, OldSource):
     def decl_tcg(self, f, tag, regno):
@@ -861,6 +1002,11 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
         """))
+    def analyze_read(self, f, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_qreg_read(ctx, {self.reg_num});
+        """))
 
 class QRegReadWrite(Register, Hvx, ReadWrite):
     def decl_tcg(self, f, tag, regno):
@@ -883,6 +1029,11 @@ def helper_hvx_desc(self, f):
         f.write(code_fmt(f"""\
             /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
         """))
+    def analyze_write(self, f, tag, regno):
+        self.decl_reg_num(f, regno)
+        f.write(code_fmt(f"""\
+            ctx_log_qreg_write(ctx, {self.reg_num});
+        """))
 
 def init_registers():
     regs = {
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (6 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:09   ` Brian Cain
  2023-12-10 22:07 ` [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions from hex_common.py Taylor Simpson
  2024-01-16  5:46 ` [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Brian Cain
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

This is the only remaining use of the is_written function.  We will
remove it in the subsequent commit.

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/attribs_def.h.inc |  1 -
 target/hexagon/hex_common.py     | 11 -----------
 2 files changed, 12 deletions(-)

diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc
index 21d457fa4a..87942d46f4 100644
--- a/target/hexagon/attribs_def.h.inc
+++ b/target/hexagon/attribs_def.h.inc
@@ -117,7 +117,6 @@ DEF_ATTRIB(IMPLICIT_READS_P1, "Reads the P1 register", "", "")
 DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
 DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
 DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
-DEF_ATTRIB(WRITES_PRED_REG, "Writes a predicate register", "", "")
 DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
 DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
 DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 4565dd1953..ca5e9630c1 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -94,10 +94,6 @@ def is_cond_call(tag):
 def calculate_attribs():
     add_qemu_macro_attrib("fREAD_PC", "A_IMPLICIT_READS_PC")
     add_qemu_macro_attrib("fTRAP", "A_IMPLICIT_READS_PC")
-    add_qemu_macro_attrib("fWRITE_P0", "A_WRITES_PRED_REG")
-    add_qemu_macro_attrib("fWRITE_P1", "A_WRITES_PRED_REG")
-    add_qemu_macro_attrib("fWRITE_P2", "A_WRITES_PRED_REG")
-    add_qemu_macro_attrib("fWRITE_P3", "A_WRITES_PRED_REG")
     add_qemu_macro_attrib("fSET_OVERFLOW", "A_IMPLICIT_WRITES_USR")
     add_qemu_macro_attrib("fSET_LPCFG", "A_IMPLICIT_WRITES_USR")
     add_qemu_macro_attrib("fLOAD", "A_SCALAR_LOAD")
@@ -122,13 +118,6 @@ def calculate_attribs():
                 continue
             macro = macros[macname]
             attribdict[tag] |= set(macro.attribs)
-    # Figure out which instructions write predicate registers
-    tagregs = get_tagregs()
-    for tag in tags:
-        regs = tagregs[tag]
-        for regtype, regid in regs:
-            if regtype == "P" and is_written(regid):
-                attribdict[tag].add("A_WRITES_PRED_REG")
     # Mark conditional jumps and calls
     #     Not all instructions are properly marked with A_CONDEXEC
     for tag in tags:
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions from hex_common.py
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (7 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute Taylor Simpson
@ 2023-12-10 22:07 ` Taylor Simpson
  2024-01-11 21:10   ` Brian Cain
  2024-01-16  5:46 ` [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Brian Cain
  9 siblings, 1 reply; 19+ messages in thread
From: Taylor Simpson @ 2023-12-10 22:07 UTC (permalink / raw)
  To: qemu-devel
  Cc: bcain, quic_mathbern, sidneym, quic_mliebel, richard.henderson,
	philmd, ale, anjo, ltaylorsimpson

These functions are no longer used after making the generators
object oriented.

Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
---
 target/hexagon/hex_common.py | 51 ------------------------------------
 1 file changed, 51 deletions(-)

diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index ca5e9630c1..195620c7ec 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -33,9 +33,6 @@
 overrides = {}  # tags with helper overrides
 idef_parser_enabled = {}  # tags enabled for idef-parser
 
-def bad_register(regtype, regid):
-    raise Exception(f"Bad register parse: regtype '{regtype}' regid '{regid}'")
-
 # We should do this as a hash for performance,
 # but to keep order let's keep it as a list.
 def uniquify(seq):
@@ -200,46 +197,6 @@ def get_tagimms():
     return dict(zip(tags, list(map(compute_tag_immediates, tags))))
 
 
-def is_pair(regid):
-    return len(regid) == 2
-
-
-def is_single(regid):
-    return len(regid) == 1
-
-
-def is_written(regid):
-    return regid[0] in "dexy"
-
-
-def is_writeonly(regid):
-    return regid[0] in "de"
-
-
-def is_read(regid):
-    return regid[0] in "stuvwxy"
-
-
-def is_readwrite(regid):
-    return regid[0] in "xy"
-
-
-def is_scalar_reg(regtype):
-    return regtype in "RPC"
-
-
-def is_hvx_reg(regtype):
-    return regtype in "VQ"
-
-
-def is_old_val(regtype, regid, tag):
-    return regtype + regid + "V" in semdict[tag]
-
-
-def is_new_val(regtype, regid, tag):
-    return regtype + regid + "N" in semdict[tag]
-
-
 def need_slot(tag):
     if (
         "A_CVI_SCATTER" not in attribdict[tag]
@@ -280,14 +237,6 @@ def skip_qemu_helper(tag):
     return tag in overrides.keys()
 
 
-def is_tmp_result(tag):
-    return "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]
-
-
-def is_new_result(tag):
-    return "A_CVI_NEW" in attribdict[tag]
-
-
 def is_idef_parser_enabled(tag):
     return tag in idef_parser_enabled
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs
  2023-12-10 22:07 ` [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs Taylor Simpson
@ 2024-01-11 21:08   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:08 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object
> oriented - gen_tcg_funcs
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> The generators are generally a bunch of Python if-then-else
> statements based on the regtype and regid.  Encapsulate regtype/regid
> into a class hierarchy.  Clients lookup the register and invoke
> methods.
> 
> This has several advantages for making the code easier to read,
> understand, and maintain
> - The class name makes it more clear what the operand does
> - All the methods for a given type of operand are together
> - Don't need hex_common.bad_register
>   If a regtype/regid is missing, the lookup in hex_common.get_register
>   will fail
> - We can remove the functions in hex_common that use regtype/regid
>   (e.g., is_read)
> 
> This patch creates the class hierarchy in hex_common and converts
> gen_tcg_funcs.py.  The other scripts will be converted in subsequent
> patches in this series.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/gen_tcg_funcs.py | 571 ++-------------------------
>  target/hexagon/hex_common.py    | 659
> ++++++++++++++++++++++++++++++++
>  2 files changed, 683 insertions(+), 547 deletions(-)
> 
> diff --git a/target/hexagon/gen_tcg_funcs.py
> b/target/hexagon/gen_tcg_funcs.py
> index 02d93bc5ce..3d8e3cb6a2 100755
> --- a/target/hexagon/gen_tcg_funcs.py
> +++ b/target/hexagon/gen_tcg_funcs.py
> @@ -23,466 +23,13 @@
>  import hex_common
> 
> 
> -##
> -## Helpers for gen_tcg_func
> -##
> -def gen_decl_ea_tcg(f, tag):
> -    f.write("    TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
> -
> -
> -def genptr_decl_pair_writable(f, tag, regtype, regid, regno):
> -    regN = f"{regtype}{regid}N"
> -    if regtype == "R":
> -        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -    elif regtype == "C":
> -        f.write(f"    const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n")
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -    f.write(f"    TCGv_i64 {regtype}{regid}V = " f"get_result_gpr_pair(ctx,
> {regN});\n")
> -
> -
> -def genptr_decl_writable(f, tag, regtype, regid, regno):
> -    regN = f"{regtype}{regid}N"
> -    if regtype == "R":
> -        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -        f.write(f"    TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
> -    elif regtype == "C":
> -        f.write(f"    const int {regN} = insn->regno[{regno}] + HEX_REG_SA0;\n")
> -        f.write(f"    TCGv {regtype}{regid}V = get_result_gpr(ctx, {regN});\n")
> -    elif regtype == "P":
> -        f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -        f.write(f"    TCGv {regtype}{regid}V = tcg_temp_new();\n")
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_decl(f, tag, regtype, regid, regno):
> -    regN = f"{regtype}{regid}N"
> -    if regtype == "R":
> -        if regid in {"ss", "tt"}:
> -            f.write(f"    TCGv_i64 {regtype}{regid}V = tcg_temp_new_i64();\n")
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"dd", "ee", "xx", "yy"}:
> -            genptr_decl_pair_writable(f, tag, regtype, regid, regno)
> -        elif regid in {"s", "t", "u", "v"}:
> -            f.write(
> -                f"    TCGv {regtype}{regid}V = " f"hex_gpr[insn->regno[{regno}]];\n"
> -            )
> -        elif regid in {"d", "e", "x", "y"}:
> -            genptr_decl_writable(f, tag, regtype, regid, regno)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid in {"s", "t", "u", "v"}:
> -            f.write(
> -                f"    TCGv {regtype}{regid}V = " f"hex_pred[insn->regno[{regno}]];\n"
> -            )
> -        elif regid in {"d", "e", "x"}:
> -            genptr_decl_writable(f, tag, regtype, regid, regno)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "C":
> -        if regid == "ss":
> -            f.write(f"    TCGv_i64 {regtype}{regid}V = " f"tcg_temp_new_i64();\n")
> -            f.write(f"    const int {regN} = insn->regno[{regno}] + "
> "HEX_REG_SA0;\n")
> -        elif regid == "dd":
> -            genptr_decl_pair_writable(f, tag, regtype, regid, regno)
> -        elif regid == "s":
> -            f.write(f"    TCGv {regtype}{regid}V = tcg_temp_new();\n")
> -            f.write(
> -                f"    const int {regtype}{regid}N = insn->regno[{regno}] + "
> -                "HEX_REG_SA0;\n"
> -            )
> -        elif regid == "d":
> -            genptr_decl_writable(f, tag, regtype, regid, regno)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "M":
> -        if regid == "u":
> -            f.write(
> -                f"    const int {regN} = insn->regno[{regno}] + HEX_REG_M0;\n"
> -            )
> -            f.write(
> -                f"    TCGv {regtype}{regid}V = hex_gpr[{regN}];\n"
> -            )
> -            f.write(
> -                f"    TCGv CS G_GNUC_UNUSED = "
> -                f"hex_gpr[{regN} - HEX_REG_M0 + HEX_REG_CS0];\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "V":
> -        if regid in {"dd"}:
> -            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
> -            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
> -            if hex_common.is_tmp_result(tag):
> -                f.write(
> -                    f"        ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 2, " "true);\n"
> -                )
> -            else:
> -                f.write(f"        ctx_future_vreg_off(ctx, {regtype}{regid}N,")
> -                f.write(" 2, true);\n")
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
> -                f.write(
> -                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
> -                    f"{regtype}{regid}V_off);\n"
> -                )
> -        elif regid in {"uu", "vv", "xx"}:
> -            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
> -            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
> -            f.write(f"        offsetof(CPUHexagonState, {regtype}{regid}V);\n")
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
> -                f.write(
> -                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
> -                    f"{regtype}{regid}V_off);\n"
> -                )
> -        elif regid in {"s", "u", "v", "w"}:
> -            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
> -            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
> -            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N);\n")
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
> -        elif regid in {"d", "x", "y"}:
> -            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
> -            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
> -            if regid == "y":
> -                f.write("        offsetof(CPUHexagonState, vtmp);\n")
> -            elif hex_common.is_tmp_result(tag):
> -                f.write(
> -                    f"        ctx_tmp_vreg_off(ctx, {regtype}{regid}N, 1, " "true);\n"
> -                )
> -            else:
> -                f.write(f"        ctx_future_vreg_off(ctx, {regtype}{regid}N,")
> -                f.write(" 1, true);\n")
> -
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
> -                f.write(
> -                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
> -                    f"{regtype}{regid}V_off);\n"
> -                )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "Q":
> -        if regid in {"d", "e", "x"}:
> -            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
> -            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
> -            f.write(f"        get_result_qreg(ctx, {regtype}{regid}N);\n")
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
> -                f.write(
> -                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
> -                    f"{regtype}{regid}V_off);\n"
> -                )
> -        elif regid in {"s", "t", "u", "v"}:
> -            f.write(f"    const int {regtype}{regid}N = " f"insn->regno[{regno}];\n")
> -            f.write(f"    const intptr_t {regtype}{regid}V_off =\n")
> -            f.write(
> -                f"        offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]);\n"
> -            )
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(f"    TCGv_ptr {regtype}{regid}V = " "tcg_temp_new_ptr();\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_decl_new(f, tag, regtype, regid, regno):
> -    if regtype == "N":
> -        if regid in {"s", "t"}:
> -            f.write(
> -                f"    TCGv {regtype}{regid}N = "
> -                f"get_result_gpr(ctx, insn->regno[{regno}]);\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid in {"t", "u", "v"}:
> -            f.write(
> -                f"    TCGv {regtype}{regid}N = "
> -                f"ctx->new_pred_value[insn->regno[{regno}]];\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "O":
> -        if regid == "s":
> -            f.write(
> -                f"    const intptr_t {regtype}{regid}N_num = "
> -                f"insn->regno[{regno}];\n"
> -            )
> -            if hex_common.skip_qemu_helper(tag):
> -                f.write(f"    const intptr_t {regtype}{regid}N_off =\n")
> -                f.write("         ctx_future_vreg_off(ctx, " f"{regtype}{regid}N_num,")
> -                f.write(" 1, true);\n")
> -            else:
> -                f.write(
> -                    f"    TCGv {regtype}{regid}N = "
> -                    f"tcg_constant_tl({regtype}{regid}N_num);\n"
> -                )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_decl_opn(f, tag, regtype, regid, i):
> -    if hex_common.is_pair(regid):
> -        genptr_decl(f, tag, regtype, regid, i)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_old_val(regtype, regid, tag):
> -            genptr_decl(f, tag, regtype, regid, i)
> -        elif hex_common.is_new_val(regtype, regid, tag):
> -            genptr_decl_new(f, tag, regtype, regid, i)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_decl_imm(f, immlett):
> -    if immlett.isupper():
> -        i = 1
> -    else:
> -        i = 0
> -    f.write(f"    int {hex_common.imm_name(immlett)} = insn->immed[{i}];\n")
> -
> -
> -def genptr_src_read(f, tag, regtype, regid):
> -    if regtype == "R":
> -        if regid in {"ss", "tt", "xx", "yy"}:
> -            f.write(
> -                f"    tcg_gen_concat_i32_i64({regtype}{regid}V, "
> -                f"hex_gpr[{regtype}{regid}N],\n"
> -            )
> -            f.write(
> -                f"                                 hex_gpr[{regtype}"
> -                f"{regid}N + 1]);\n"
> -            )
> -        elif regid in {"x", "y"}:
> -            ## For read/write registers, we need to get the original value into
> -            ## the result TCGv.  For conditional instructions, this is done in
> -            ## gen_start_packet.  For unconditional instructions, we do it here.
> -            if "A_CONDEXEC" not in hex_common.attribdict[tag]:
> -                f.write(
> -                    f"    tcg_gen_mov_tl({regtype}{regid}V, "
> -                    f"hex_gpr[{regtype}{regid}N]);\n"
> -                )
> -        elif regid not in {"s", "t", "u", "v"}:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid == "x":
> -            f.write(
> -                f"    tcg_gen_mov_tl({regtype}{regid}V, "
> -                f"hex_pred[{regtype}{regid}N]);\n"
> -            )
> -        elif regid not in {"s", "t", "u", "v"}:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "C":
> -        if regid == "ss":
> -            f.write(
> -                f"    gen_read_ctrl_reg_pair(ctx, {regtype}{regid}N, "
> -                f"{regtype}{regid}V);\n"
> -            )
> -        elif regid == "s":
> -            f.write(
> -                f"    gen_read_ctrl_reg(ctx, {regtype}{regid}N, "
> -                f"{regtype}{regid}V);\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "M":
> -        if regid != "u":
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "V":
> -        if regid in {"uu", "vv", "xx"}:
> -            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
> -            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N),\n")
> -            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
> -            f.write("    tcg_gen_gvec_mov(MO_64,\n")
> -            f.write(f"        {regtype}{regid}V_off + sizeof(MMVector),\n")
> -            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N ^ 1),\n")
> -            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
> -        elif regid in {"s", "u", "v", "w"}:
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(
> -                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
> -                    f"{regtype}{regid}V_off);\n"
> -                )
> -        elif regid in {"x", "y"}:
> -            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
> -            f.write(f"        vreg_src_off(ctx, {regtype}{regid}N),\n")
> -            f.write("        sizeof(MMVector), sizeof(MMVector));\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "Q":
> -        if regid in {"s", "t", "u", "v"}:
> -            if not hex_common.skip_qemu_helper(tag):
> -                f.write(
> -                    f"    tcg_gen_addi_ptr({regtype}{regid}V, tcg_env, "
> -                    f"{regtype}{regid}V_off);\n"
> -                )
> -        elif regid in {"x"}:
> -            f.write(f"    tcg_gen_gvec_mov(MO_64, {regtype}{regid}V_off,\n")
> -            f.write(
> -                f"        offsetof(CPUHexagonState, " f"QRegs[{regtype}{regid}N]),\n"
> -            )
> -            f.write("        sizeof(MMQReg), sizeof(MMQReg));\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_src_read_new(f, regtype, regid):
> -    if regtype == "N":
> -        if regid not in {"s", "t"}:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid not in {"t", "u", "v"}:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "O":
> -        if regid != "s":
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_src_read_opn(f, regtype, regid, tag):
> -    if hex_common.is_pair(regid):
> -        genptr_src_read(f, tag, regtype, regid)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_old_val(regtype, regid, tag):
> -            genptr_src_read(f, tag, regtype, regid)
> -        elif hex_common.is_new_val(regtype, regid, tag):
> -            genptr_src_read_new(f, regtype, regid)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def gen_helper_call_opn(f, tag, regtype, regid, i):
> -    if i > 0:
> -        f.write(", ")
> -    if hex_common.is_pair(regid):
> -        f.write(f"{regtype}{regid}V")
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_old_val(regtype, regid, tag):
> -            f.write(f"{regtype}{regid}V")
> -        elif hex_common.is_new_val(regtype, regid, tag):
> -            f.write(f"{regtype}{regid}N")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def gen_helper_decl_imm(f, immlett):
> -    f.write(
> -        f"    TCGv tcgv_{hex_common.imm_name(immlett)} = "
> -        f"tcg_constant_tl({hex_common.imm_name(immlett)});\n"
> -    )
> -
> -
> -def gen_helper_call_imm(f, immlett):
> -    f.write(f", tcgv_{hex_common.imm_name(immlett)}")
> -
> -
> -def genptr_dst_write_pair(f, tag, regtype, regid):
> -    f.write(f"    gen_log_reg_write_pair(ctx, {regtype}{regid}N, "
> -            f"{regtype}{regid}V);\n")
> -
> -
> -def genptr_dst_write(f, tag, regtype, regid):
> -    if regtype == "R":
> -        if regid in {"dd", "xx", "yy"}:
> -            genptr_dst_write_pair(f, tag, regtype, regid)
> -        elif regid in {"d", "e", "x", "y"}:
> -            f.write(
> -                f"    gen_log_reg_write(ctx, {regtype}{regid}N, "
> -                f"{regtype}{regid}V);\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid in {"d", "e", "x"}:
> -            f.write(
> -                f"    gen_log_pred_write(ctx, {regtype}{regid}N, "
> -                f"{regtype}{regid}V);\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "C":
> -        if regid == "dd":
> -            f.write(
> -                f"    gen_write_ctrl_reg_pair(ctx, {regtype}{regid}N, "
> -                f"{regtype}{regid}V);\n"
> -            )
> -        elif regid == "d":
> -            f.write(
> -                f"    gen_write_ctrl_reg(ctx, {regtype}{regid}N, "
> -                f"{regtype}{regid}V);\n"
> -            )
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_dst_write_ext(f, tag, regtype, regid, newv="EXT_DFL"):
> -    if regtype == "V":
> -        if regid in {"xx"}:
> -            f.write(
> -                f"    gen_log_vreg_write_pair(ctx, {regtype}{regid}V_off, "
> -                f"{regtype}{regid}N, {newv});\n"
> -            )
> -        elif regid in {"y"}:
> -            f.write(
> -                f"    gen_log_vreg_write(ctx, {regtype}{regid}V_off, "
> -                f"{regtype}{regid}N, {newv});\n"
> -            )
> -        elif regid not in {"dd", "d", "x"}:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "Q":
> -        if regid not in {"d", "e", "x"}:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def genptr_dst_write_opn(f, regtype, regid, tag):
> -    if hex_common.is_pair(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            if hex_common.is_tmp_result(tag):
> -                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
> -            else:
> -                genptr_dst_write_ext(f, tag, regtype, regid)
> -        else:
> -            genptr_dst_write(f, tag, regtype, regid)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            if hex_common.is_new_result(tag):
> -                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_NEW")
> -            elif hex_common.is_tmp_result(tag):
> -                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_TMP")
> -            else:
> -                genptr_dst_write_ext(f, tag, regtype, regid, "EXT_DFL")
> -        else:
> -            genptr_dst_write(f, tag, regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
>  ##
>  ## Generate the TCG code to call the helper
>  ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
>  ##     We produce:
>  ##    static void generate_A2_add(DisasContext *ctx)
>  ##    {
> -##        Insn *insn __attribute__((unused)) = ctx->insn;
> +##        Insn *insn G_GNUC_UNUSED = ctx->insn;
>  ##        const int RdN = insn->regno[0];
>  ##        TCGv RdV = get_result_gpr(ctx, RdN);
>  ##        TCGv RsV = hex_gpr[insn->regno[1]];
> @@ -501,44 +48,27 @@ def gen_tcg_func(f, tag, regs, imms):
>      f.write(f"static void generate_{tag}(DisasContext *ctx)\n")
>      f.write("{\n")
> 
> -    f.write("    Insn *insn __attribute__((unused)) = ctx->insn;\n")
> +    f.write("    Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
> 
>      if hex_common.need_ea(tag):
> -        gen_decl_ea_tcg(f, tag)
> -    i = 0
> +        f.write("    TCGv EA G_GNUC_UNUSED = tcg_temp_new();\n")
> +
>      ## Declare all the operands (regs and immediates)
> +    i = 0
>      for regtype, regid in regs:
> -        genptr_decl_opn(f, tag, regtype, regid, i)
> +        reg = hex_common.get_register(tag, regtype, regid)
> +        reg.decl_tcg(f, tag, i)
>          i += 1
>      for immlett, bits, immshift in imms:
> -        genptr_decl_imm(f, immlett)
> -
> -    if "A_PRIV" in hex_common.attribdict[tag]:
> -        f.write("    fCHECKFORPRIV();\n")
> -    if "A_GUEST" in hex_common.attribdict[tag]:
> -        f.write("    fCHECKFORGUEST();\n")
> -
> -    ## Read all the inputs
> -    for regtype, regid in regs:
> -        if hex_common.is_read(regid):
> -            genptr_src_read_opn(f, regtype, regid, tag)
> +        i = 1 if immlett.isupper() else 0
> +        f.write(f"    int {hex_common.imm_name(immlett)} = insn-
> >immed[{i}];\n")
> 
>      if hex_common.is_idef_parser_enabled(tag):
>          declared = []
>          ## Handle registers
>          for regtype, regid in regs:
> -            if hex_common.is_pair(regid) or (
> -                hex_common.is_single(regid)
> -                and hex_common.is_old_val(regtype, regid, tag)
> -            ):
> -                declared.append(f"{regtype}{regid}V")
> -                if regtype == "M":
> -                    declared.append("CS")
> -            elif hex_common.is_new_val(regtype, regid, tag):
> -                declared.append(f"{regtype}{regid}N")
> -            else:
> -                hex_common.bad_register(regtype, regid)
> -
> +            reg = hex_common.get_register(tag, regtype, regid)
> +            reg.idef_arg(declared)
>          ## Handle immediates
>          for immlett, bits, immshift in imms:
>              declared.append(hex_common.imm_name(immlett))
> @@ -550,76 +80,22 @@ def gen_tcg_func(f, tag, regs, imms):
>          f.write(f"    fGEN_TCG_{tag}({hex_common.semdict[tag]});\n")
>      else:
>          ## Generate the call to the helper
> -        for immlett, bits, immshift in imms:
> -            gen_helper_decl_imm(f, immlett)
> -        if hex_common.need_pkt_has_multi_cof(tag):
> -            f.write("    TCGv pkt_has_multi_cof = ")
> -            f.write("tcg_constant_tl(ctx->pkt->pkt_has_multi_cof);\n")
> -        if hex_common.need_pkt_need_commit(tag):
> -            f.write("    TCGv pkt_need_commit = ")
> -            f.write("tcg_constant_tl(ctx->need_commit);\n")
> -        if hex_common.need_part1(tag):
> -            f.write("    TCGv part1 = tcg_constant_tl(insn->part1);\n")
> -        if hex_common.need_slot(tag):
> -            f.write("    TCGv slotval = gen_slotval(ctx);\n")
> -        if hex_common.need_PC(tag):
> -            f.write("    TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
> -        if hex_common.helper_needs_next_PC(tag):
> -            f.write("    TCGv next_PC = tcg_constant_tl(ctx->next_PC);\n")
> -        f.write(f"    gen_helper_{tag}(")
> -        i = 0
> -        ## If there is a scalar result, it is the return type
> -        for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                if hex_common.is_hvx_reg(regtype):
> -                    continue
> -                gen_helper_call_opn(f, tag, regtype, regid, i)
> -                i += 1
> -        if i > 0:
> -            f.write(", ")
> -        f.write("tcg_env")
> -        i = 1
> -        ## For conditional instructions, we pass in the destination register
> -        if "A_CONDEXEC" in hex_common.attribdict[tag]:
> -            for regtype, regid in regs:
> -                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
> -                    regtype
> -                ):
> -                    gen_helper_call_opn(f, tag, regtype, regid, i)
> -                    i += 1
> -        for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                if not hex_common.is_hvx_reg(regtype):
> -                    continue
> -                gen_helper_call_opn(f, tag, regtype, regid, i)
> -                i += 1
> -        for regtype, regid in regs:
> -            if hex_common.is_read(regid):
> -                if hex_common.is_hvx_reg(regtype) and
> hex_common.is_readwrite(regid):
> -                    continue
> -                gen_helper_call_opn(f, tag, regtype, regid, i)
> -                i += 1
> -        for immlett, bits, immshift in imms:
> -            gen_helper_call_imm(f, immlett)
> +        declared = []
> +        ret_type = hex_common.helper_ret_type(tag, regs).call_arg
> +        if ret_type != "void":
> +            declared.append(ret_type)
> +
> +        for arg in hex_common.helper_args(tag, regs, imms):
> +            declared.append(arg.call_arg)
> 
> -        if hex_common.need_pkt_has_multi_cof(tag):
> -            f.write(", pkt_has_multi_cof")
> -        if hex_common.need_pkt_need_commit(tag):
> -            f.write(", pkt_need_commit")
> -        if hex_common.need_PC(tag):
> -            f.write(", PC")
> -        if hex_common.helper_needs_next_PC(tag):
> -            f.write(", next_PC")
> -        if hex_common.need_slot(tag):
> -            f.write(", slotval")
> -        if hex_common.need_part1(tag):
> -            f.write(", part1")
> -        f.write(");\n")
> +        arguments = ", ".join(declared)
> +        f.write(f"    gen_helper_{tag}({arguments});\n")
> 
>      ## Write all the outputs
>      for regtype, regid in regs:
> -        if hex_common.is_written(regid):
> -            genptr_dst_write_opn(f, regtype, regid, tag)
> +        reg = hex_common.get_register(tag, regtype, regid)
> +        if reg.is_written():
> +            reg.log_write(f, tag)
> 
>      f.write("}\n\n")
> 
> @@ -637,6 +113,7 @@ def main():
>      hex_common.read_overrides_file(sys.argv[3])
>      hex_common.read_overrides_file(sys.argv[4])
>      hex_common.calculate_attribs()
> +    hex_common.init_registers()
>      ## Whether or not idef-parser is enabled is
>      ## determined by the number of arguments to
>      ## this script:
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index 0da65d6dd6..979f198a30 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -20,12 +20,15 @@
>  import sys
>  import re
>  import string
> +import textwrap
> 
>  behdict = {}  # tag ->behavior
>  semdict = {}  # tag -> semantics
>  attribdict = {}  # tag -> attributes
>  macros = {}  # macro -> macro information...
>  attribinfo = {}  # Register information and misc
> +registers = {}  # register -> register functions
> +new_registers = {}
>  tags = []  # list of all tags
>  overrides = {}  # tags with helper overrides
>  idef_parser_enabled = {}  # tags enabled for idef-parser
> @@ -276,6 +279,10 @@ def helper_needs_next_PC(tag):
>      return "A_CALL" in attribdict[tag]
> 
> 
> +def need_next_PC(tag):
> +    return "A_CALL" in attribdict[tag]
> +
> +
>  def need_pkt_has_multi_cof(tag):
>      return "A_COF" in attribdict[tag]
> 
> @@ -350,3 +357,655 @@ def read_idef_parser_enabled_file(name):
>      with open(name, "r") as idef_parser_enabled_file:
>          lines = idef_parser_enabled_file.read().strip().split("\n")
>          idef_parser_enabled = set(lines)
> +
> +
> +def is_predicated(tag):
> +    return "A_CONDEXEC" in attribdict[tag]
> +
> +
> +def code_fmt(txt):
> +    return textwrap.indent(textwrap.dedent(txt), "    ")
> +
> +
> +def hvx_newv(tag):
> +    if "A_CVI_NEW" in attribdict[tag]:
> +        return "EXT_NEW"
> +    elif "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]:
> +        return "EXT_TMP"
> +    else:
> +        return "EXT_DFL"
> +
> +def vreg_offset_func(tag):
> +    if "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in attribdict[tag]:
> +        return "ctx_tmp_vreg_off"
> +    else:
> +        return "ctx_future_vreg_off"
> +
> +class HelperArg:
> +    def __init__(self, proto_arg, call_arg, func_arg):
> +        self.proto_arg = proto_arg
> +        self.call_arg = call_arg
> +        self.func_arg = func_arg
> +
> +class Register:
> +    def __init__(self, regtype, regid):
> +        self.regtype = regtype
> +        self.regid = regid
> +        self.reg_num = f"{regtype}{regid}N"
> +    def decl_reg_num(self, f, regno):
> +        f.write(code_fmt(f"""\
> +            const int {self.reg_num} = insn->regno[{regno}];
> +        """))
> +    def idef_arg(self, declared):
> +        declared.append(self.reg_tcg())
> +    def helper_arg(self):
> +        return HelperArg(
> +            self.helper_proto_type(),
> +            self.reg_tcg(),
> +            f"{self.helper_arg_type()} {self.helper_arg_name()}"
> +        )
> +
> +#
> +# Every register is either Single or Pair or Hvx
> +#
> +class Scalar:
> +    def is_scalar_reg(self):
> +        return True
> +    def is_hvx_reg(self):
> +        return False
> +    def helper_arg_name(self):
> +        return self.reg_tcg()
> +
> +class Single(Scalar):
> +    def helper_proto_type(self):
> +        return "s32"
> +    def helper_arg_type(self):
> +        return "int32_t"
> +
> +class Pair(Scalar):
> +    def helper_proto_type(self):
> +        return "s64"
> +    def helper_arg_type(self):
> +        return "int64_t"
> +
> +class Hvx:
> +    def is_scalar_reg(self):
> +        return False
> +    def is_hvx_reg(self):
> +        return True
> +    def hvx_off(self):
> +        return f"{self.reg_tcg()}_off"
> +    def helper_proto_type(self):
> +        return "ptr"
> +    def helper_arg_type(self):
> +        return "void *"
> +    def helper_arg_name(self):
> +        return f"{self.reg_tcg()}_void"
> +
> +#
> +# Every register is either Dest or OldSource or NewSource or ReadWrite
> +#
> +class Dest:
> +    def reg_tcg(self):
> +        return f"{self.regtype}{self.regid}V"
> +    def is_written(self):
> +        return True
> +    def is_writeonly(self):
> +        return True
> +    def is_read(self):
> +        return False
> +    def is_readwrite(self):
> +        return False
> +
> +class Source:
> +    def is_written(self):
> +        return False
> +    def is_writeonly(self):
> +        return False
> +    def is_read(self):
> +        return True
> +    def is_readwrite(self):
> +        return False
> +
> +class OldSource(Source):
> +    def reg_tcg(self):
> +        return f"{self.regtype}{self.regid}V"
> +
> +class NewSource(Source):
> +    def reg_tcg(self):
> +        return f"{self.regtype}{self.regid}N"
> +
> +class ReadWrite:
> +    def reg_tcg(self):
> +        return f"{self.regtype}{self.regid}V"
> +    def is_written(self):
> +        return True
> +    def is_writeonly(self):
> +        return False
> +    def is_read(self):
> +        return True
> +    def is_readwrite(self):
> +        return True
> +
> +class GprDest(Register, Single, Dest):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class GprSource(Register, Single, OldSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
> +        """))
> +
> +class GprNewSource(Register, Single, NewSource):
> +    def decl_tcg(self, f, tag, regno):
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
> +        """))
> +
> +class GprReadWrite(Register, Single, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
> +        """))
> +        ## For read/write registers, we need to get the original value into
> +        ## the result TCGv.  For predicated instructions, this is done in
> +        ## gen_start_packet.  For un-predicated instructions, we do it here.
> +        if not is_predicated(tag):
> +            f.write(code_fmt(f"""\
> +                tcg_gen_mov_tl({self.reg_tcg()}, hex_gpr[{self.reg_num}]);
> +            """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class ControlDest(Register, Single, Dest):
> +    def decl_reg_num(self, f, regno):
> +        f.write(code_fmt(f"""\
> +            const int {self.reg_num} = insn->regno[{regno}]  + HEX_REG_SA0;
> +        """))
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = get_result_gpr(ctx, {self.reg_num});
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class ControlSource(Register, Single, OldSource):
> +    def decl_reg_num(self, f, regno):
> +        f.write(code_fmt(f"""\
> +            const int {self.reg_num} = insn->regno[{regno}]  + HEX_REG_SA0;
> +        """))
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno);
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = tcg_temp_new();
> +            gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class ModifierSource(Register, Single, OldSource):
> +    def decl_reg_num(self, f, regno):
> +        f.write(code_fmt(f"""\
> +            const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_M0;
> +        """))
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
> +            TCGv CS G_GNUC_UNUSED =
> +                hex_gpr[{self.reg_num} - HEX_REG_M0 + HEX_REG_CS0];
> +        """))
> +    def idef_arg(self, declared):
> +        declared.append(self.reg_tcg())
> +        declared.append("CS")
> +
> +class PredDest(Register, Single, Dest):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = tcg_temp_new();
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class PredSource(Register, Single, OldSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
> +        """))
> +
> +class PredNewSource(Register, Single, NewSource):
> +    def decl_tcg(self, f, tag, regno):
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
> +        """))
> +
> +class PredReadWrite(Register, Single, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv {self.reg_tcg()} = tcg_temp_new();
> +            tcg_gen_mov_tl({self.reg_tcg()}, hex_pred[{self.reg_num}]);
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class PairDest(Register, Pair, Dest):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv_i64 {self.reg_tcg()} =
> +                get_result_gpr_pair(ctx, {self.reg_num});
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class PairSource(Register, Pair, OldSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
> +            tcg_gen_concat_i32_i64({self.reg_tcg()},
> +                                    hex_gpr[{self.reg_num}],
> +                                    hex_gpr[{self.reg_num} + 1]);
> +        """))
> +
> +class PairReadWrite(Register, Pair, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv_i64 {self.reg_tcg()} =
> +                get_result_gpr_pair(ctx, {self.reg_num});
> +            tcg_gen_concat_i32_i64({self.reg_tcg()},
> +                                   hex_gpr[{self.reg_num}],
> +                                   hex_gpr[{self.reg_num} + 1]);
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class ControlPairDest(Register, Pair, Dest):
> +    def decl_reg_num(self, f, regno):
> +        f.write(code_fmt(f"""\
> +            const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
> +        """))
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv_i64 {self.reg_tcg()} =
> +                get_result_gpr_pair(ctx, {self.reg_num});
> +        """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class ControlPairSource(Register, Pair, OldSource):
> +    def decl_reg_num(self, f, regno):
> +        f.write(code_fmt(f"""\
> +            const int {self.reg_num} = insn->regno[{regno}] + HEX_REG_SA0;
> +        """))
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
> +            gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
> +        """))
> +
> +class VRegDest(Register, Hvx, Dest):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +    def log_write(self, f, tag):
> +        pass
> +
> +class VRegSource(Register, Hvx, OldSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} = vreg_src_off(ctx, {self.reg_num});
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +
> +class VRegNewSource(Register, Hvx, NewSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        if skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                const intptr_t {self.hvx_off()} =
> +                    ctx_future_vreg_off(ctx, {self.reg_num}, 1, true);
> +            """))
> +
> +class VRegReadWrite(Register, Hvx, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 1, true);
> +            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
> +                             vreg_src_off(ctx, {self.reg_num}),
> +                             sizeof(MMVector), sizeof(MMVector));
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +    def log_write(self, f, tag):
> +        pass
> +
> +class VRegTmp(Register, Hvx, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} = offsetof(CPUHexagonState, vtmp);
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +                tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
> +                                 vreg_src_off(ctx, {self.reg_num}),
> +                                 sizeof(MMVector), sizeof(MMVector));
> +            """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
> +                               {hvx_newv(tag)});
> +        """))
> +
> +class VRegPairDest(Register, Hvx, Dest):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                {vreg_offset_func(tag)}(ctx, {self.reg_num}, 2, true);
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +    def log_write(self, f, tag):
> +        pass
> +
> +class VRegPairSource(Register, Hvx, OldSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                offsetof(CPUHexagonState, {self.reg_tcg()});
> +            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
> +                             vreg_src_off(ctx, {self.reg_num}),
> +                             sizeof(MMVector), sizeof(MMVector));
> +            tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
> +                             vreg_src_off(ctx, {self.reg_num} ^ 1),
> +                             sizeof(MMVector), sizeof(MMVector));
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +
> +class VRegPairReadWrite(Register, Hvx, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                offsetof(CPUHexagonState, {self.reg_tcg()});
> +            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
> +                             vreg_src_off(ctx, {self.reg_num}),
> +                             sizeof(MMVector), sizeof(MMVector));
> +            tcg_gen_gvec_mov(MO_64, {self.hvx_off()} + sizeof(MMVector),
> +                             vreg_src_off(ctx, {self.reg_num} ^ 1),
> +                             sizeof(MMVector), sizeof(MMVector));
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +    def log_write(self, f, tag):
> +        f.write(code_fmt(f"""\
> +            gen_log_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
> +                                    {hvx_newv(tag)});
> +        """))
> +
> +class QRegDest(Register, Hvx, Dest):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                get_result_qreg(ctx, {self.reg_num});
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +    def log_write(self, f, tag):
> +        pass
> +
> +class QRegSource(Register, Hvx, OldSource):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                offsetof(CPUHexagonState, QRegs[{self.reg_num}]);
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +
> +class QRegReadWrite(Register, Hvx, ReadWrite):
> +    def decl_tcg(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            const intptr_t {self.hvx_off()} =
> +                get_result_qreg(ctx, {self.reg_num});
> +            tcg_gen_gvec_mov(MO_64, {self.hvx_off()},
> +                             offsetof(CPUHexagonState, QRegs[{self.reg_num}]),
> +                             sizeof(MMQReg), sizeof(MMQReg));
> +        """))
> +        if not skip_qemu_helper(tag):
> +            f.write(code_fmt(f"""\
> +                TCGv_ptr {self.reg_tcg()} = tcg_temp_new_ptr();
> +                tcg_gen_addi_ptr({self.reg_tcg()}, tcg_env, {self.hvx_off()});
> +            """))
> +    def log_write(self, f, tag):
> +        pass
> +
> +def init_registers():
> +    regs = {
> +        GprDest("R", "d"),
> +        GprDest("R", "e"),
> +        GprSource("R", "s"),
> +        GprSource("R", "t"),
> +        GprSource("R", "u"),
> +        GprSource("R", "v"),
> +        GprReadWrite("R", "x"),
> +        GprReadWrite("R", "y"),
> +        ControlDest("C", "d"),
> +        ControlSource("C", "s"),
> +        ModifierSource("M", "u"),
> +        PredDest("P", "d"),
> +        PredDest("P", "e"),
> +        PredSource("P", "s"),
> +        PredSource("P", "t"),
> +        PredSource("P", "u"),
> +        PredSource("P", "v"),
> +        PredReadWrite("P", "x"),
> +        PairDest("R", "dd"),
> +        PairDest("R", "ee"),
> +        PairSource("R", "ss"),
> +        PairSource("R", "tt"),
> +        PairReadWrite("R", "xx"),
> +        PairReadWrite("R", "yy"),
> +        ControlPairDest("C", "dd"),
> +        ControlPairSource("C", "ss"),
> +        VRegDest("V", "d"),
> +        VRegSource("V", "s"),
> +        VRegSource("V", "u"),
> +        VRegSource("V", "v"),
> +        VRegSource("V", "w"),
> +        VRegReadWrite("V", "x"),
> +        VRegTmp("V", "y"),
> +        VRegPairDest("V", "dd"),
> +        VRegPairSource("V", "uu"),
> +        VRegPairSource("V", "vv"),
> +        VRegPairReadWrite("V", "xx"),
> +        QRegDest("Q", "d"),
> +        QRegDest("Q", "e"),
> +        QRegSource("Q", "s"),
> +        QRegSource("Q", "t"),
> +        QRegSource("Q", "u"),
> +        QRegSource("Q", "v"),
> +        QRegReadWrite("Q", "x"),
> +    }
> +    for reg in regs:
> +        registers[f"{reg.regtype}{reg.regid}"] = reg
> +
> +    new_regs = {
> +        GprNewSource("N", "s"),
> +        GprNewSource("N", "t"),
> +        PredNewSource("P", "t"),
> +        PredNewSource("P", "u"),
> +        PredNewSource("P", "v"),
> +        VRegNewSource("O", "s"),
> +    }
> +    for reg in new_regs:
> +        new_registers[f"{reg.regtype}{reg.regid}"] = reg
> +
> +def get_register(tag, regtype, regid):
> +    if f"{regtype}{regid}V" in semdict[tag]:
> +        return registers[f"{regtype}{regid}"]
> +    else:
> +        return new_registers[f"{regtype}{regid}"]
> +
> +def helper_ret_type(tag, regs):
> +    ## If there is a scalar result, it is the return type
> +    return_type = HelperArg( "void", "void", "void")
> +    numscalarresults = 0
> +    for regtype, regid in regs:
> +        reg = get_register(tag, regtype, regid)
> +        if reg.is_written() and reg.is_scalar_reg():
> +            return_type = HelperArg(
> +                reg.helper_proto_type(),
> +                reg.reg_tcg(),
> +                reg.helper_arg_type()
> +            )
> +    if numscalarresults > 1:
> +        raise Exception("numscalarresults > 1")
> +    return return_type
> +
> +def helper_args(tag, regs, imms):
> +    args = []
> +
> +    ## First argument is the CPU state
> +    args.append(HelperArg(
> +        "env",
> +        "tcg_env",
> +        "CPUHexagonState *env"
> +    ))
> +
> +    ## For predicated instructions, we pass in the destination register
> +    if is_predicated(tag):
> +        for regtype, regid in regs:
> +            reg = get_register(tag, regtype, regid)
> +            if reg.is_writeonly() and not reg.is_hvx_reg():
> +                args.append(reg.helper_arg())
> +
> +    ## Pass the HVX destination registers
> +    for regtype, regid in regs:
> +        reg = get_register(tag, regtype, regid)
> +        if reg.is_written() and reg.is_hvx_reg():
> +            args.append(reg.helper_arg())
> +
> +    ## Pass the source registers
> +    for regtype, regid in regs:
> +        reg = get_register(tag, regtype, regid)
> +        if reg.is_read() and not (reg.is_hvx_reg() and reg.is_readwrite()):
> +            args.append(reg.helper_arg())
> +
> +    ## Pass the immediates
> +    for immlett, bits, immshift in imms:
> +        args.append(HelperArg(
> +            "s32",
> +            f"tcg_constant_tl({imm_name(immlett)})",
> +            f"int32_t {imm_name(immlett)}"
> +        ))
> +
> +    ## Other stuff the helper might need
> +    if need_pkt_has_multi_cof(tag):
> +        args.append(HelperArg(
> +            "i32",
> +            "tcg_constant_tl(ctx->pkt->pkt_has_multi_cof)",
> +            "uint32_t pkt_has_multi_cof"
> +        ))
> +    if need_pkt_need_commit(tag):
> +        args.append(HelperArg(
> +            "i32",
> +            "tcg_constant_tl(ctx->need_commit)",
> +            "uint32_t pkt_need_commit"
> +        ))
> +    if need_PC(tag):
> +        args.append(HelperArg(
> +            "i32",
> +            "tcg_constant_tl(ctx->pkt->pc)",
> +            "target_ulong PC"
> +        ))
> +    if need_next_PC(tag):
> +        args.append(HelperArg(
> +            "i32",
> +            "tcg_constant_tl(ctx->next_PC)",
> +            "target_ulong next_PC"
> +        ))
> +    if need_slot(tag):
> +        args.append(HelperArg(
> +            "i32",
> +            "gen_slotval(ctx)",
> +            "uint32_t slotval"
> +        ))
> +    if need_part1(tag):
> +        args.append(HelperArg(
> +            "i32",
> +            "tcg_constant_tl(insn->part1)"
> +            "uint32_t part1"
> +        ))
> +    return args
> --
> 2.34.1

Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos
  2023-12-10 22:07 ` [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos Taylor Simpson
@ 2024-01-11 21:08   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:08 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object
> oriented - gen_helper_protos
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/gen_helper_protos.py | 149 ++--------------------------
>  target/hexagon/hex_common.py        |   7 --
>  2 files changed, 8 insertions(+), 148 deletions(-)
> 
> diff --git a/target/hexagon/gen_helper_protos.py
> b/target/hexagon/gen_helper_protos.py
> index 131043795a..c82b0f54e4 100755
> --- a/target/hexagon/gen_helper_protos.py
> +++ b/target/hexagon/gen_helper_protos.py
> @@ -22,39 +22,6 @@
>  import string
>  import hex_common
> 
> -##
> -## Helpers for gen_helper_prototype
> -##
> -def_helper_types = {
> -    "N": "s32",
> -    "O": "s32",
> -    "P": "s32",
> -    "M": "s32",
> -    "C": "s32",
> -    "R": "s32",
> -    "V": "ptr",
> -    "Q": "ptr",
> -}
> -
> -def_helper_types_pair = {
> -    "R": "s64",
> -    "C": "s64",
> -    "S": "s64",
> -    "G": "s64",
> -    "V": "ptr",
> -    "Q": "ptr",
> -}
> -
> -
> -def gen_def_helper_opn(f, tag, regtype, regid, i):
> -    if hex_common.is_pair(regid):
> -        f.write(f", {def_helper_types_pair[regtype]}")
> -    elif hex_common.is_single(regid):
> -        f.write(f", {def_helper_types[regtype]}")
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
>  ##
>  ## Generate the DEF_HELPER prototype for an instruction
>  ##     For A2_add: Rd32=add(Rs32,Rt32)
> @@ -65,116 +32,15 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
>      regs = tagregs[tag]
>      imms = tagimms[tag]
> 
> -    numresults = 0
> -    numscalarresults = 0
> -    numscalarreadwrite = 0
> -    for regtype, regid in regs:
> -        if hex_common.is_written(regid):
> -            numresults += 1
> -            if hex_common.is_scalar_reg(regtype):
> -                numscalarresults += 1
> -        if hex_common.is_readwrite(regid):
> -            if hex_common.is_scalar_reg(regtype):
> -                numscalarreadwrite += 1
> -
> -    if numscalarresults > 1:
> -        ## The helper is bogus when there is more than one result
> -        f.write(f"DEF_HELPER_1({tag}, void, env)\n")
> -    else:
> -        ## Figure out how many arguments the helper will take
> -        if numscalarresults == 0:
> -            def_helper_size = len(regs) + len(imms) + numscalarreadwrite + 1
> -            if hex_common.need_pkt_has_multi_cof(tag):
> -                def_helper_size += 1
> -            if hex_common.need_pkt_need_commit(tag):
> -                def_helper_size += 1
> -            if hex_common.need_part1(tag):
> -                def_helper_size += 1
> -            if hex_common.need_slot(tag):
> -                def_helper_size += 1
> -            if hex_common.need_PC(tag):
> -                def_helper_size += 1
> -            if hex_common.helper_needs_next_PC(tag):
> -                def_helper_size += 1
> -            if hex_common.need_condexec_reg(tag, regs):
> -                def_helper_size += 1
> -            f.write(f"DEF_HELPER_{def_helper_size}({tag}")
> -            ## The return type is void
> -            f.write(", void")
> -        else:
> -            def_helper_size = len(regs) + len(imms) + numscalarreadwrite
> -            if hex_common.need_pkt_has_multi_cof(tag):
> -                def_helper_size += 1
> -            if hex_common.need_pkt_need_commit(tag):
> -                def_helper_size += 1
> -            if hex_common.need_part1(tag):
> -                def_helper_size += 1
> -            if hex_common.need_slot(tag):
> -                def_helper_size += 1
> -            if hex_common.need_PC(tag):
> -                def_helper_size += 1
> -            if hex_common.need_condexec_reg(tag, regs):
> -                def_helper_size += 1
> -            if hex_common.helper_needs_next_PC(tag):
> -                def_helper_size += 1
> -            f.write(f"DEF_HELPER_{def_helper_size}({tag}")
> -
> -        ## Generate the qemu DEF_HELPER type for each result
> -        ## Iterate over this list twice
> -        ## - Emit the scalar result
> -        ## - Emit the vector result
> -        i = 0
> -        for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                if not hex_common.is_hvx_reg(regtype):
> -                    gen_def_helper_opn(f, tag, regtype, regid, i)
> -                i += 1
> -
> -        ## Put the env between the outputs and inputs
> -        f.write(", env")
> -        i += 1
> -
> -        # Second pass
> -        for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                if hex_common.is_hvx_reg(regtype):
> -                    gen_def_helper_opn(f, tag, regtype, regid, i)
> -                    i += 1
> -
> -        ## For conditional instructions, we pass in the destination register
> -        if "A_CONDEXEC" in hex_common.attribdict[tag]:
> -            for regtype, regid in regs:
> -                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
> -                    regtype
> -                ):
> -                    gen_def_helper_opn(f, tag, regtype, regid, i)
> -                    i += 1
> +    declared = []
> +    ret_type = hex_common.helper_ret_type(tag, regs).proto_arg
> +    declared.append(ret_type)
> 
> -        ## Generate the qemu type for each input operand (regs and immediates)
> -        for regtype, regid in regs:
> -            if hex_common.is_read(regid):
> -                if hex_common.is_hvx_reg(regtype) and
> hex_common.is_readwrite(regid):
> -                    continue
> -                gen_def_helper_opn(f, tag, regtype, regid, i)
> -                i += 1
> -        for immlett, bits, immshift in imms:
> -            f.write(", s32")
> +    for arg in hex_common.helper_args(tag, regs, imms):
> +        declared.append(arg.proto_arg)
> 
> -        ## Add the arguments for the instruction pkt_has_multi_cof,
> -        ## pkt_needs_commit, PC, next_PC, slot, and part1 (if needed)
> -        if hex_common.need_pkt_has_multi_cof(tag):
> -            f.write(", i32")
> -        if hex_common.need_pkt_need_commit(tag):
> -            f.write(', i32')
> -        if hex_common.need_PC(tag):
> -            f.write(", i32")
> -        if hex_common.helper_needs_next_PC(tag):
> -            f.write(", i32")
> -        if hex_common.need_slot(tag):
> -            f.write(", i32")
> -        if hex_common.need_part1(tag):
> -            f.write(" , i32")
> -        f.write(")\n")
> +    arguments = ", ".join(declared)
> +    f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
> 
> 
>  def main():
> @@ -195,6 +61,7 @@ def main():
>      if is_idef_parser_enabled:
>          hex_common.read_idef_parser_enabled_file(sys.argv[5])
>      hex_common.calculate_attribs()
> +    hex_common.init_registers()
>      tagregs = hex_common.get_tagregs()
>      tagimms = hex_common.get_tagimms()
> 
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index 979f198a30..2abd653e6d 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -290,13 +290,6 @@ def need_pkt_has_multi_cof(tag):
>  def need_pkt_need_commit(tag):
>      return 'A_IMPLICIT_WRITES_USR' in attribdict[tag]
> 
> -def need_condexec_reg(tag, regs):
> -    if "A_CONDEXEC" in attribdict[tag]:
> -        for regtype, regid in regs:
> -            if is_writeonly(regid) and not is_hvx_reg(regtype):
> -                return True
> -    return False
> -
> 
>  def skip_qemu_helper(tag):
>      return tag in overrides.keys()
> --
> 2.34.1


Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs
  2023-12-10 22:07 ` [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs Taylor Simpson
@ 2024-01-11 21:08   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:08 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object
> oriented - gen_idef_parser_funcs
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/gen_idef_parser_funcs.py | 20 ++++----------------
>  1 file changed, 4 insertions(+), 16 deletions(-)
> 
> diff --git a/target/hexagon/gen_idef_parser_funcs.py
> b/target/hexagon/gen_idef_parser_funcs.py
> index f4518e653f..550a48cb7b 100644
> --- a/target/hexagon/gen_idef_parser_funcs.py
> +++ b/target/hexagon/gen_idef_parser_funcs.py
> @@ -46,6 +46,7 @@ def main():
>      hex_common.read_semantics_file(sys.argv[1])
>      hex_common.read_attribs_file(sys.argv[2])
>      hex_common.calculate_attribs()
> +    hex_common.init_registers()
>      tagregs = hex_common.get_tagregs()
>      tagimms = hex_common.get_tagimms()
> 
> @@ -132,22 +133,9 @@ def main():
> 
>              arguments = []
>              for regtype, regid in regs:
> -                prefix = "in " if hex_common.is_read(regid) else ""
> -
> -                is_pair = hex_common.is_pair(regid)
> -                is_single_old = hex_common.is_single(regid) and
> hex_common.is_old_val(
> -                    regtype, regid, tag
> -                )
> -                is_single_new = hex_common.is_single(regid) and
> hex_common.is_new_val(
> -                    regtype, regid, tag
> -                )
> -
> -                if is_pair or is_single_old:
> -                    arguments.append(f"{prefix}{regtype}{regid}V")
> -                elif is_single_new:
> -                    arguments.append(f"{prefix}{regtype}{regid}N")
> -                else:
> -                    hex_common.bad_register(regtype, regid)
> +                reg = hex_common.get_register(tag, regtype, regid)
> +                prefix = "in " if reg.is_read() else ""
> +                arguments.append(f"{prefix}{reg.reg_tcg()}")
> 
>              for immlett, bits, immshift in imms:
>                  arguments.append(hex_common.imm_name(immlett))
> --
> 2.34.1

Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs
  2023-12-10 22:07 ` [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs Taylor Simpson
@ 2024-01-11 21:09   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:09 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object
> oriented - gen_helper_funcs
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/gen_helper_funcs.py | 368 +++++------------------------
>  target/hexagon/hex_common.py       |  48 +++-
>  2 files changed, 103 insertions(+), 313 deletions(-)
> 
> diff --git a/target/hexagon/gen_helper_funcs.py
> b/target/hexagon/gen_helper_funcs.py
> index ce21d3b688..9cc3d69c49 100755
> --- a/target/hexagon/gen_helper_funcs.py
> +++ b/target/hexagon/gen_helper_funcs.py
> @@ -23,181 +23,14 @@
>  import hex_common
> 
> 
> -##
> -## Helpers for gen_helper_function
> -##
> -def gen_decl_ea(f):
> -    f.write("    uint32_t EA;\n")
> -
> -
> -def gen_helper_return_type(f, regtype, regid, regno):
> -    if regno > 1:
> -        f.write(", ")
> -    f.write("int32_t")
> -
> -
> -def gen_helper_return_type_pair(f, regtype, regid, regno):
> -    if regno > 1:
> -        f.write(", ")
> -    f.write("int64_t")
> -
> -
> -def gen_helper_arg(f, regtype, regid, regno):
> -    if regno > 0:
> -        f.write(", ")
> -    f.write(f"int32_t {regtype}{regid}V")
> -
> -
> -def gen_helper_arg_new(f, regtype, regid, regno):
> -    if regno >= 0:
> -        f.write(", ")
> -    f.write(f"int32_t {regtype}{regid}N")
> -
> -
> -def gen_helper_arg_pair(f, regtype, regid, regno):
> -    if regno >= 0:
> -        f.write(", ")
> -    f.write(f"int64_t {regtype}{regid}V")
> -
> -
> -def gen_helper_arg_ext(f, regtype, regid, regno):
> -    if regno > 0:
> -        f.write(", ")
> -    f.write(f"void *{regtype}{regid}V_void")
> -
> -
> -def gen_helper_arg_ext_pair(f, regtype, regid, regno):
> -    if regno > 0:
> -        f.write(", ")
> -    f.write(f"void *{regtype}{regid}V_void")
> -
> -
> -def gen_helper_arg_opn(f, regtype, regid, i, tag):
> -    if hex_common.is_pair(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            gen_helper_arg_ext_pair(f, regtype, regid, i)
> -        else:
> -            gen_helper_arg_pair(f, regtype, regid, i)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_old_val(regtype, regid, tag):
> -            if hex_common.is_hvx_reg(regtype):
> -                gen_helper_arg_ext(f, regtype, regid, i)
> -            else:
> -                gen_helper_arg(f, regtype, regid, i)
> -        elif hex_common.is_new_val(regtype, regid, tag):
> -            gen_helper_arg_new(f, regtype, regid, i)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def gen_helper_arg_imm(f, immlett):
> -    f.write(f", int32_t {hex_common.imm_name(immlett)}")
> -
> -
> -def gen_helper_dest_decl(f, regtype, regid, regno, subfield=""):
> -    f.write(f"    int32_t {regtype}{regid}V{subfield} = 0;\n")
> -
> -
> -def gen_helper_dest_decl_pair(f, regtype, regid, regno, subfield=""):
> -    f.write(f"    int64_t {regtype}{regid}V{subfield} = 0;\n")
> -
> -
> -def gen_helper_dest_decl_ext(f, regtype, regid):
> -    if regtype == "Q":
> -        f.write(
> -            f"    /* {regtype}{regid}V is *(MMQReg *)" f"({regtype}{regid}V_void)
> */\n"
> -        )
> -    else:
> -        f.write(
> -            f"    /* {regtype}{regid}V is *(MMVector *)"
> -            f"({regtype}{regid}V_void) */\n"
> -        )
> -
> -
> -def gen_helper_dest_decl_ext_pair(f, regtype, regid, regno):
> -    f.write(
> -        f"    /* {regtype}{regid}V is *(MMVectorPair *))"
> -        f"{regtype}{regid}V_void) */\n"
> -    )
> -
> -
> -def gen_helper_dest_decl_opn(f, regtype, regid, i):
> -    if hex_common.is_pair(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            gen_helper_dest_decl_ext_pair(f, regtype, regid, i)
> -        else:
> -            gen_helper_dest_decl_pair(f, regtype, regid, i)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            gen_helper_dest_decl_ext(f, regtype, regid)
> -        else:
> -            gen_helper_dest_decl(f, regtype, regid, i)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def gen_helper_src_var_ext(f, regtype, regid):
> -    if regtype == "Q":
> -        f.write(
> -            f"    /* {regtype}{regid}V is *(MMQReg *)" f"({regtype}{regid}V_void)
> */\n"
> -        )
> -    else:
> -        f.write(
> -            f"    /* {regtype}{regid}V is *(MMVector *)"
> -            f"({regtype}{regid}V_void) */\n"
> -        )
> -
> -
> -def gen_helper_src_var_ext_pair(f, regtype, regid, regno):
> -    f.write(
> -        f"    /* {regtype}{regid}V{regno} is *(MMVectorPair *)"
> -        f"({regtype}{regid}V{regno}_void) */\n"
> -    )
> -
> -
> -def gen_helper_return(f, regtype, regid, regno):
> -    f.write(f"    return {regtype}{regid}V;\n")
> -
> -
> -def gen_helper_return_pair(f, regtype, regid, regno):
> -    f.write(f"    return {regtype}{regid}V;\n")
> -
> -
> -def gen_helper_dst_write_ext(f, regtype, regid):
> -    return
> -
> -
> -def gen_helper_dst_write_ext_pair(f, regtype, regid):
> -    return
> -
> -
> -def gen_helper_return_opn(f, regtype, regid, i):
> -    if hex_common.is_pair(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            gen_helper_dst_write_ext_pair(f, regtype, regid)
> -        else:
> -            gen_helper_return_pair(f, regtype, regid, i)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_hvx_reg(regtype):
> -            gen_helper_dst_write_ext(f, regtype, regid)
> -        else:
> -            gen_helper_return(f, regtype, regid, i)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
>  ##
>  ## Generate the TCG code to call the helper
>  ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
>  ##     We produce:
>  ##       int32_t HELPER(A2_add)(CPUHexagonState *env, int32_t RsV, int32_t
> RtV)
>  ##       {
> -##           uint32_t slot __attribute__(unused)) = 4;
>  ##           int32_t RdV = 0;
>  ##           { RdV=RsV+RtV;}
> -##           COUNT_HELPER(A2_add);
>  ##           return RdV;
>  ##       }
>  ##
> @@ -205,151 +38,67 @@ def gen_helper_function(f, tag, tagregs, tagimms):
>      regs = tagregs[tag]
>      imms = tagimms[tag]
> 
> -    numresults = 0
> -    numscalarresults = 0
> -    numscalarreadwrite = 0
> -    for regtype, regid in regs:
> -        if hex_common.is_written(regid):
> -            numresults += 1
> -            if hex_common.is_scalar_reg(regtype):
> -                numscalarresults += 1
> -        if hex_common.is_readwrite(regid):
> -            if hex_common.is_scalar_reg(regtype):
> -                numscalarreadwrite += 1
> -
> -    if numscalarresults > 1:
> -        ## The helper is bogus when there is more than one result
> -        f.write(
> -            f"void HELPER({tag})(CPUHexagonState *env) " f"{{
> BOGUS_HELPER({tag}); }}\n"
> -        )
> -    else:
> -        ## The return type of the function is the type of the destination
> -        ## register (if scalar)
> -        i = 0
> +    ret_type = hex_common.helper_ret_type(tag, regs).func_arg
> +
> +    declared = []
> +    for arg in hex_common.helper_args(tag, regs, imms):
> +        declared.append(arg.func_arg)
> +
> +    arguments = ", ".join(declared)
> +    f.write(f"{ret_type} HELPER({tag})({arguments})\n")
> +    f.write("{\n")
> +    if hex_common.need_ea(tag):
> +        f.write(hex_common.code_fmt(f"""\
> +            uint32_t EA;
> +        """))
> +    ## Declare the return variable
> +    if not hex_common.is_predicated(tag):
>          for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                if hex_common.is_pair(regid):
> -                    if hex_common.is_hvx_reg(regtype):
> -                        continue
> -                    else:
> -                        gen_helper_return_type_pair(f, regtype, regid, i)
> -                elif hex_common.is_single(regid):
> -                    if hex_common.is_hvx_reg(regtype):
> -                        continue
> -                    else:
> -                        gen_helper_return_type(f, regtype, regid, i)
> -                else:
> -                    hex_common.bad_register(regtype, regid)
> -            i += 1
> +            reg = hex_common.get_register(tag, regtype, regid)
> +            if reg.is_writeonly() and not reg.is_hvx_reg():
> +                f.write(hex_common.code_fmt(f"""\
> +                    {reg.helper_arg_type()} {reg.helper_arg_name()} = 0;
> +                """))
> 
> -        if numscalarresults == 0:
> -            f.write("void")
> -        f.write(f" HELPER({tag})(CPUHexagonState *env")
> -
> -        ## Arguments include the vector destination operands
> -        i = 1
> -        for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                if hex_common.is_pair(regid):
> -                    if hex_common.is_hvx_reg(regtype):
> -                        gen_helper_arg_ext_pair(f, regtype, regid, i)
> -                    else:
> -                        continue
> -                elif hex_common.is_single(regid):
> -                    if hex_common.is_hvx_reg(regtype):
> -                        gen_helper_arg_ext(f, regtype, regid, i)
> -                    else:
> -                        # This is the return value of the function
> -                        continue
> -                else:
> -                    hex_common.bad_register(regtype, regid)
> -                i += 1
> -
> -        ## For conditional instructions, we pass in the destination register
> -        if "A_CONDEXEC" in hex_common.attribdict[tag]:
> -            for regtype, regid in regs:
> -                if hex_common.is_writeonly(regid) and not hex_common.is_hvx_reg(
> -                    regtype
> -                ):
> -                    gen_helper_arg_opn(f, regtype, regid, i, tag)
> -                    i += 1
> -
> -        ## Arguments to the helper function are the source regs and immediates
> -        for regtype, regid in regs:
> -            if hex_common.is_read(regid):
> -                if hex_common.is_hvx_reg(regtype) and
> hex_common.is_readwrite(regid):
> -                    continue
> -                gen_helper_arg_opn(f, regtype, regid, i, tag)
> -                i += 1
> -        for immlett, bits, immshift in imms:
> -            gen_helper_arg_imm(f, immlett)
> -            i += 1
> -
> -        if hex_common.need_pkt_has_multi_cof(tag):
> -            f.write(", uint32_t pkt_has_multi_cof")
> -        if (hex_common.need_pkt_need_commit(tag)):
> -            f.write(", uint32_t pkt_need_commit")
> -
> -        if hex_common.need_PC(tag):
> -            if i > 0:
> -                f.write(", ")
> -            f.write("target_ulong PC")
> -            i += 1
> -        if hex_common.helper_needs_next_PC(tag):
> -            if i > 0:
> -                f.write(", ")
> -            f.write("target_ulong next_PC")
> -            i += 1
> -        if hex_common.need_slot(tag):
> -            if i > 0:
> -                f.write(", ")
> -            f.write("uint32_t slotval")
> -            i += 1
> -        if hex_common.need_part1(tag):
> -            if i > 0:
> -                f.write(", ")
> -            f.write("uint32_t part1")
> -        f.write(")\n{\n")
> -        if hex_common.need_ea(tag):
> -            gen_decl_ea(f)
> -        ## Declare the return variable
> -        i = 0
> -        if "A_CONDEXEC" not in hex_common.attribdict[tag]:
> -            for regtype, regid in regs:
> -                if hex_common.is_writeonly(regid):
> -                    gen_helper_dest_decl_opn(f, regtype, regid, i)
> -                i += 1
> -
> -        for regtype, regid in regs:
> -            if hex_common.is_read(regid):
> -                if hex_common.is_pair(regid):
> -                    if hex_common.is_hvx_reg(regtype):
> -                        gen_helper_src_var_ext_pair(f, regtype, regid, i)
> -                elif hex_common.is_single(regid):
> -                    if hex_common.is_hvx_reg(regtype):
> -                        gen_helper_src_var_ext(f, regtype, regid)
> -                else:
> -                    hex_common.bad_register(regtype, regid)
> -
> -        if hex_common.need_slot(tag):
> -            if "A_LOAD" in hex_common.attribdict[tag]:
> -                f.write("    bool pkt_has_store_s1 = slotval & 0x1;\n")
> -            f.write("    uint32_t slot = slotval >> 1;\n")
> -
> -        if "A_FPOP" in hex_common.attribdict[tag]:
> -            f.write("    arch_fpop_start(env);\n")
> -
> -        f.write(f"    {hex_common.semdict[tag]}\n")
> -
> -        if "A_FPOP" in hex_common.attribdict[tag]:
> -            f.write("    arch_fpop_end(env);\n")
> +    ## Print useful information about HVX registers
> +    for regtype, regid in regs:
> +        reg = hex_common.get_register(tag, regtype, regid)
> +        if reg.is_hvx_reg():
> +            reg.helper_hvx_desc(f)
> +
> +    if hex_common.need_slot(tag):
> +        if "A_LOAD" in hex_common.attribdict[tag]:
> +            f.write(hex_common.code_fmt(f"""\
> +                bool pkt_has_store_s1 = slotval & 0x1;
> +            """))
> +        f.write(hex_common.code_fmt(f"""\
> +            uint32_t slot = slotval >> 1;
> +        """))
> +
> +    if "A_FPOP" in hex_common.attribdict[tag]:
> +        f.write(hex_common.code_fmt(f"""\
> +            arch_fpop_start(env);
> +        """))
> +
> +    f.write(hex_common.code_fmt(f"""\
> +        {hex_common.semdict[tag]}
> +    """))
> +
> +    if "A_FPOP" in hex_common.attribdict[tag]:
> +        f.write(hex_common.code_fmt(f"""\
> +            arch_fpop_end(env);
> +        """))
> +
> +    ## Return the scalar result
> +    for regtype, regid in regs:
> +        reg = hex_common.get_register(tag, regtype, regid)
> +        if reg.is_written() and not reg.is_hvx_reg():
> +            f.write(hex_common.code_fmt(f"""\
> +                return {reg.helper_arg_name()};
> +            """))
> 
> -        ## Save/return the return variable
> -        for regtype, regid in regs:
> -            if hex_common.is_written(regid):
> -                gen_helper_return_opn(f, regtype, regid, i)
> -        f.write("}\n\n")
> -        ## End of the helper definition
> +    f.write("}\n\n")
> +    ## End of the helper definition
> 
> 
>  def main():
> @@ -370,6 +119,7 @@ def main():
>      if is_idef_parser_enabled:
>          hex_common.read_idef_parser_enabled_file(sys.argv[5])
>      hex_common.calculate_attribs()
> +    hex_common.init_registers()
>      tagregs = hex_common.get_tagregs()
>      tagimms = hex_common.get_tagimms()
> 
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index 2abd653e6d..fc9ce4e2b0 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -275,10 +275,6 @@ def need_PC(tag):
>      return "A_IMPLICIT_READS_PC" in attribdict[tag]
> 
> 
> -def helper_needs_next_PC(tag):
> -    return "A_CALL" in attribdict[tag]
> -
> -
>  def need_next_PC(tag):
>      return "A_CALL" in attribdict[tag]
> 
> @@ -680,6 +676,10 @@ def decl_tcg(self, f, tag, regno):
>              """))
>      def log_write(self, f, tag):
>          pass
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegSource(Register, Hvx, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -692,6 +692,10 @@ 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 helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegNewSource(Register, Hvx, NewSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -701,6 +705,10 @@ def decl_tcg(self, f, tag, regno):
>                  const intptr_t {self.hvx_off()} =
>                      ctx_future_vreg_off(ctx, {self.reg_num}, 1, true);
>              """))
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegReadWrite(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -719,6 +727,10 @@ def decl_tcg(self, f, tag, regno):
>              """))
>      def log_write(self, f, tag):
>          pass
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegTmp(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -739,6 +751,10 @@ def log_write(self, f, tag):
>              gen_log_vreg_write(ctx, {self.hvx_off()}, {self.reg_num},
>                                 {hvx_newv(tag)});
>          """))
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegPairDest(Register, Hvx, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -754,6 +770,10 @@ def decl_tcg(self, f, tag, regno):
>              """))
>      def log_write(self, f, tag):
>          pass
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegPairSource(Register, Hvx, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -773,6 +793,10 @@ 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 helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
> +        """))
> 
>  class VRegPairReadWrite(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -797,6 +821,10 @@ def log_write(self, f, tag):
>              gen_log_vreg_write_pair(ctx, {self.hvx_off()}, {self.reg_num},
>                                      {hvx_newv(tag)});
>          """))
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
> +        """))
> 
>  class QRegDest(Register, Hvx, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -812,6 +840,10 @@ def decl_tcg(self, f, tag, regno):
>              """))
>      def log_write(self, f, tag):
>          pass
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
> +        """))
> 
>  class QRegSource(Register, Hvx, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -825,6 +857,10 @@ 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 helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
> +        """))
> 
>  class QRegReadWrite(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -843,6 +879,10 @@ def decl_tcg(self, f, tag, regno):
>              """))
>      def log_write(self, f, tag):
>          pass
> +    def helper_hvx_desc(self, f):
> +        f.write(code_fmt(f"""\
> +            /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
> +        """))
> 
>  def init_registers():
>      regs = {
> --
> 2.34.1

Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs
  2023-12-10 22:07 ` [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs Taylor Simpson
@ 2024-01-11 21:09   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:09 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object
> oriented - gen_op_regs
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> Reviewed-by: Brian Cain <bcain@quicinc.com>
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/gen_op_regs.py | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/target/hexagon/gen_op_regs.py b/target/hexagon/gen_op_regs.py
> index a8a7712129..7b7b33895a 100755
> --- a/target/hexagon/gen_op_regs.py
> +++ b/target/hexagon/gen_op_regs.py
> @@ -70,6 +70,7 @@ def strip_reg_prefix(x):
>  def main():
>      hex_common.read_semantics_file(sys.argv[1])
>      hex_common.read_attribs_file(sys.argv[2])
> +    hex_common.init_registers()
>      tagregs = hex_common.get_tagregs(full=True)
>      tagimms = hex_common.get_tagimms()
> 
> @@ -80,11 +81,12 @@ def main():
>              wregs = []
>              regids = ""
>              for regtype, regid, _, numregs in regs:
> -                if hex_common.is_read(regid):
> +                reg = hex_common.get_register(tag, regtype, regid)
> +                if reg.is_read():
>                      if regid[0] not in regids:
>                          regids += regid[0]
>                      rregs.append(regtype + regid + numregs)
> -                if hex_common.is_written(regid):
> +                if reg.is_written():
>                      wregs.append(regtype + regid + numregs)
>                      if regid[0] not in regids:
>                          regids += regid[0]
> --
> 2.34.1

Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs
  2023-12-10 22:07 ` [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs Taylor Simpson
@ 2024-01-11 21:09   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:09 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object
> oriented - gen_analyze_funcs
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> This patch conflicts with
> https://lists.gnu.org/archive/html/qemu-devel/2023-11/msg00729.html
> If that series goes in first, we'll rework this patch and vice versa.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/gen_analyze_funcs.py | 163 +---------------------------
>  target/hexagon/hex_common.py        | 151 ++++++++++++++++++++++++++
>  2 files changed, 157 insertions(+), 157 deletions(-)
> 
> diff --git a/target/hexagon/gen_analyze_funcs.py
> b/target/hexagon/gen_analyze_funcs.py
> index c3b521abef..a9af666cef 100755
> --- a/target/hexagon/gen_analyze_funcs.py
> +++ b/target/hexagon/gen_analyze_funcs.py
> @@ -23,162 +23,6 @@
>  import hex_common
> 
> 
> -##
> -## Helpers for gen_analyze_func
> -##
> -def is_predicated(tag):
> -    return "A_CONDEXEC" in hex_common.attribdict[tag]
> -
> -
> -def analyze_opn_old(f, tag, regtype, regid, regno):
> -    regN = f"{regtype}{regid}N"
> -    predicated = "true" if is_predicated(tag) else "false"
> -    if regtype == "R":
> -        if regid in {"ss", "tt"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_reg_read_pair(ctx, {regN});\n")
> -        elif regid in {"dd", "ee", "xx", "yy"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n")
> -        elif regid in {"s", "t", "u", "v"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
> -        elif regid in {"d", "e", "x", "y"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_reg_write(ctx, {regN}, {predicated});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid in {"s", "t", "u", "v"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_pred_read(ctx, {regN});\n")
> -        elif regid in {"d", "e", "x"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_pred_write(ctx, {regN});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "C":
> -        if regid == "ss":
> -            f.write(
> -                f"    const int {regN} = insn->regno[{regno}] "
> -                "+ HEX_REG_SA0;\n"
> -            )
> -            f.write(f"    ctx_log_reg_read_pair(ctx, {regN});\n")
> -        elif regid == "dd":
> -            f.write(f"    const int {regN} = insn->regno[{regno}] " "+
> HEX_REG_SA0;\n")
> -            f.write(f"    ctx_log_reg_write_pair(ctx, {regN}, {predicated});\n")
> -        elif regid == "s":
> -            f.write(
> -                f"    const int {regN} = insn->regno[{regno}] "
> -                "+ HEX_REG_SA0;\n"
> -            )
> -            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
> -        elif regid == "d":
> -            f.write(f"    const int {regN} = insn->regno[{regno}] " "+
> HEX_REG_SA0;\n")
> -            f.write(f"    ctx_log_reg_write(ctx, {regN}, {predicated});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "M":
> -        if regid == "u":
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "V":
> -        newv = "EXT_DFL"
> -        if hex_common.is_new_result(tag):
> -            newv = "EXT_NEW"
> -        elif hex_common.is_tmp_result(tag):
> -            newv = "EXT_TMP"
> -        if regid in {"dd", "xx"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(
> -                f"    ctx_log_vreg_write_pair(ctx, {regN}, {newv}, " f"{predicated});\n"
> -            )
> -        elif regid in {"uu", "vv"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_vreg_read_pair(ctx, {regN});\n")
> -        elif regid in {"s", "u", "v", "w"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_vreg_read(ctx, {regN});\n")
> -        elif regid in {"d", "x", "y"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_vreg_write(ctx, {regN}, {newv}, "
> f"{predicated});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "Q":
> -        if regid in {"d", "e", "x"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_qreg_write(ctx, {regN});\n")
> -        elif regid in {"s", "t", "u", "v"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_qreg_read(ctx, {regN});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "G":
> -        if regid in {"dd"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"d"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"ss"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"s"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "S":
> -        if regid in {"dd"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"d"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"ss"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        elif regid in {"s"}:
> -            f.write(f"//    const int {regN} = insn->regno[{regno}];\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def analyze_opn_new(f, tag, regtype, regid, regno):
> -    regN = f"{regtype}{regid}N"
> -    if regtype == "N":
> -        if regid in {"s", "t"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_reg_read(ctx, {regN});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "P":
> -        if regid in {"t", "u", "v"}:
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_pred_read(ctx, {regN});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    elif regtype == "O":
> -        if regid == "s":
> -            f.write(f"    const int {regN} = insn->regno[{regno}];\n")
> -            f.write(f"    ctx_log_vreg_read(ctx, {regN});\n")
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
> -def analyze_opn(f, tag, regtype, regid, i):
> -    if hex_common.is_pair(regid):
> -        analyze_opn_old(f, tag, regtype, regid, i)
> -    elif hex_common.is_single(regid):
> -        if hex_common.is_old_val(regtype, regid, tag):
> -            analyze_opn_old(f, tag, regtype, regid, i)
> -        elif hex_common.is_new_val(regtype, regid, tag):
> -            analyze_opn_new(f, tag, regtype, regid, i)
> -        else:
> -            hex_common.bad_register(regtype, regid)
> -    else:
> -        hex_common.bad_register(regtype, regid)
> -
> -
>  ##
>  ## Generate the code to analyze the instruction
>  ##     For A2_add: Rd32=add(Rs32,Rt32), { RdV=RsV+RtV;}
> @@ -203,7 +47,11 @@ def gen_analyze_func(f, tag, regs, imms):
>      i = 0
>      ## Analyze all the registers
>      for regtype, regid in regs:
> -        analyze_opn(f, tag, regtype, regid, i)
> +        reg = hex_common.get_register(tag, regtype, regid)
> +        if reg.is_written():
> +            reg.analyze_write(f, tag, i)
> +        else:
> +            reg.analyze_read(f, i)
>          i += 1
> 
>      has_generated_helper = not hex_common.skip_qemu_helper(
> @@ -236,6 +84,7 @@ def main():
>      if is_idef_parser_enabled:
>          hex_common.read_idef_parser_enabled_file(sys.argv[5])
>      hex_common.calculate_attribs()
> +    hex_common.init_registers()
>      tagregs = hex_common.get_tagregs()
>      tagimms = hex_common.get_tagimms()
> 
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index fc9ce4e2b0..4565dd1953 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -486,6 +486,12 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
> +        """))
> 
>  class GprSource(Register, Single, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -493,12 +499,22 @@ def decl_tcg(self, f, tag, regno):
>          f.write(code_fmt(f"""\
>              TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_read(ctx, {self.reg_num});
> +        """))
> 
>  class GprNewSource(Register, Single, NewSource):
>      def decl_tcg(self, f, tag, regno):
>          f.write(code_fmt(f"""\
>              TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_read(ctx, {self.reg_num});
> +        """))
> 
>  class GprReadWrite(Register, Single, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -517,6 +533,12 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
> +        """))
> 
>  class ControlDest(Register, Single, Dest):
>      def decl_reg_num(self, f, regno):
> @@ -532,6 +554,12 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
> +        """))
> 
>  class ControlSource(Register, Single, OldSource):
>      def decl_reg_num(self, f, regno):
> @@ -544,6 +572,11 @@ def decl_tcg(self, f, tag, regno):
>              TCGv {self.reg_tcg()} = tcg_temp_new();
>              gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_read(ctx, {self.reg_num});
> +        """))
> 
>  class ModifierSource(Register, Single, OldSource):
>      def decl_reg_num(self, f, regno):
> @@ -560,6 +593,11 @@ def decl_tcg(self, f, tag, regno):
>      def idef_arg(self, declared):
>          declared.append(self.reg_tcg())
>          declared.append("CS")
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_read(ctx, {self.reg_num});
> +        """))
> 
>  class PredDest(Register, Single, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -571,6 +609,11 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_pred_write(ctx, {self.reg_num});
> +        """))
> 
>  class PredSource(Register, Single, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -578,12 +621,22 @@ def decl_tcg(self, f, tag, regno):
>          f.write(code_fmt(f"""\
>              TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_pred_read(ctx, {self.reg_num});
> +        """))
> 
>  class PredNewSource(Register, Single, NewSource):
>      def decl_tcg(self, f, tag, regno):
>          f.write(code_fmt(f"""\
>              TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_pred_read(ctx, {self.reg_num});
> +        """))
> 
>  class PredReadWrite(Register, Single, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -596,6 +649,11 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_pred_write(ctx, {self.reg_num});
> +        """))
> 
>  class PairDest(Register, Pair, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -608,6 +666,12 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
> +        """))
> 
>  class PairSource(Register, Pair, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -618,6 +682,11 @@ def decl_tcg(self, f, tag, regno):
>                                      hex_gpr[{self.reg_num}],
>                                      hex_gpr[{self.reg_num} + 1]);
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_read_pair(ctx, {self.reg_num});
> +        """))
> 
>  class PairReadWrite(Register, Pair, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -633,6 +702,12 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
> +        """))
> 
>  class ControlPairDest(Register, Pair, Dest):
>      def decl_reg_num(self, f, regno):
> @@ -649,6 +724,12 @@ def log_write(self, f, tag):
>          f.write(code_fmt(f"""\
>              gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
> +        """))
> 
>  class ControlPairSource(Register, Pair, OldSource):
>      def decl_reg_num(self, f, regno):
> @@ -661,6 +742,11 @@ def decl_tcg(self, f, tag, regno):
>              TCGv_i64 {self.reg_tcg()} = tcg_temp_new_i64();
>              gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_reg_read_pair(ctx, {self.reg_num});
> +        """))
> 
>  class VRegDest(Register, Hvx, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -680,6 +766,13 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        newv = hvx_newv(tag)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
> +        """))
> 
>  class VRegSource(Register, Hvx, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -696,6 +789,11 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_read(ctx, {self.reg_num});
> +        """))
> 
>  class VRegNewSource(Register, Hvx, NewSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -709,6 +807,11 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_read(ctx, {self.reg_num});
> +        """))
> 
>  class VRegReadWrite(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -731,6 +834,13 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        newv = hvx_newv(tag)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
> +        """))
> 
>  class VRegTmp(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -755,6 +865,13 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        newv = hvx_newv(tag)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
> +        """))
> 
>  class VRegPairDest(Register, Hvx, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -774,6 +891,13 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        newv = hvx_newv(tag)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
> +        """))
> 
>  class VRegPairSource(Register, Hvx, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -797,6 +921,11 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_read_pair(ctx, {self.reg_num});
> +        """))
> 
>  class VRegPairReadWrite(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -825,6 +954,13 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        newv = hvx_newv(tag)
> +        predicated = "true" if is_predicated(tag) else "false"
> +        f.write(code_fmt(f"""\
> +            ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
> +        """))
> 
>  class QRegDest(Register, Hvx, Dest):
>      def decl_tcg(self, f, tag, regno):
> @@ -844,6 +980,11 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_qreg_write(ctx, {self.reg_num});
> +        """))
> 
>  class QRegSource(Register, Hvx, OldSource):
>      def decl_tcg(self, f, tag, regno):
> @@ -861,6 +1002,11 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_read(self, f, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_qreg_read(ctx, {self.reg_num});
> +        """))
> 
>  class QRegReadWrite(Register, Hvx, ReadWrite):
>      def decl_tcg(self, f, tag, regno):
> @@ -883,6 +1029,11 @@ def helper_hvx_desc(self, f):
>          f.write(code_fmt(f"""\
>              /* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
>          """))
> +    def analyze_write(self, f, tag, regno):
> +        self.decl_reg_num(f, regno)
> +        f.write(code_fmt(f"""\
> +            ctx_log_qreg_write(ctx, {self.reg_num});
> +        """))
> 
>  def init_registers():
>      regs = {
> --
> 2.34.1

Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute
  2023-12-10 22:07 ` [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute Taylor Simpson
@ 2024-01-11 21:09   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:09 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused
> WRITES_PRED_REG attribute
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> This is the only remaining use of the is_written function.  We will
> remove it in the subsequent commit.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/attribs_def.h.inc |  1 -
>  target/hexagon/hex_common.py     | 11 -----------
>  2 files changed, 12 deletions(-)
> 
> diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc
> index 21d457fa4a..87942d46f4 100644
> --- a/target/hexagon/attribs_def.h.inc
> +++ b/target/hexagon/attribs_def.h.inc
> @@ -117,7 +117,6 @@ DEF_ATTRIB(IMPLICIT_READS_P1, "Reads the P1
> register", "", "")
>  DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
>  DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
>  DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
> -DEF_ATTRIB(WRITES_PRED_REG, "Writes a predicate register", "", "")
>  DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
>  DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
>  DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index 4565dd1953..ca5e9630c1 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -94,10 +94,6 @@ def is_cond_call(tag):
>  def calculate_attribs():
>      add_qemu_macro_attrib("fREAD_PC", "A_IMPLICIT_READS_PC")
>      add_qemu_macro_attrib("fTRAP", "A_IMPLICIT_READS_PC")
> -    add_qemu_macro_attrib("fWRITE_P0", "A_WRITES_PRED_REG")
> -    add_qemu_macro_attrib("fWRITE_P1", "A_WRITES_PRED_REG")
> -    add_qemu_macro_attrib("fWRITE_P2", "A_WRITES_PRED_REG")
> -    add_qemu_macro_attrib("fWRITE_P3", "A_WRITES_PRED_REG")
>      add_qemu_macro_attrib("fSET_OVERFLOW", "A_IMPLICIT_WRITES_USR")
>      add_qemu_macro_attrib("fSET_LPCFG", "A_IMPLICIT_WRITES_USR")
>      add_qemu_macro_attrib("fLOAD", "A_SCALAR_LOAD")
> @@ -122,13 +118,6 @@ def calculate_attribs():
>                  continue
>              macro = macros[macname]
>              attribdict[tag] |= set(macro.attribs)
> -    # Figure out which instructions write predicate registers
> -    tagregs = get_tagregs()
> -    for tag in tags:
> -        regs = tagregs[tag]
> -        for regtype, regid in regs:
> -            if regtype == "P" and is_written(regid):
> -                attribdict[tag].add("A_WRITES_PRED_REG")
>      # Mark conditional jumps and calls
>      #     Not all instructions are properly marked with A_CONDEXEC
>      for tag in tags:
> --
> 2.34.1


Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions from hex_common.py
  2023-12-10 22:07 ` [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions from hex_common.py Taylor Simpson
@ 2024-01-11 21:10   ` Brian Cain
  0 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-11 21:10 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions
> from hex_common.py
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> These functions are no longer used after making the generators
> object oriented.
> 
> Signed-off-by: Taylor Simpson <ltaylorsimpson@gmail.com>
> ---
>  target/hexagon/hex_common.py | 51 ------------------------------------
>  1 file changed, 51 deletions(-)
> 
> diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
> index ca5e9630c1..195620c7ec 100755
> --- a/target/hexagon/hex_common.py
> +++ b/target/hexagon/hex_common.py
> @@ -33,9 +33,6 @@
>  overrides = {}  # tags with helper overrides
>  idef_parser_enabled = {}  # tags enabled for idef-parser
> 
> -def bad_register(regtype, regid):
> -    raise Exception(f"Bad register parse: regtype '{regtype}' regid '{regid}'")
> -
>  # We should do this as a hash for performance,
>  # but to keep order let's keep it as a list.
>  def uniquify(seq):
> @@ -200,46 +197,6 @@ def get_tagimms():
>      return dict(zip(tags, list(map(compute_tag_immediates, tags))))
> 
> 
> -def is_pair(regid):
> -    return len(regid) == 2
> -
> -
> -def is_single(regid):
> -    return len(regid) == 1
> -
> -
> -def is_written(regid):
> -    return regid[0] in "dexy"
> -
> -
> -def is_writeonly(regid):
> -    return regid[0] in "de"
> -
> -
> -def is_read(regid):
> -    return regid[0] in "stuvwxy"
> -
> -
> -def is_readwrite(regid):
> -    return regid[0] in "xy"
> -
> -
> -def is_scalar_reg(regtype):
> -    return regtype in "RPC"
> -
> -
> -def is_hvx_reg(regtype):
> -    return regtype in "VQ"
> -
> -
> -def is_old_val(regtype, regid, tag):
> -    return regtype + regid + "V" in semdict[tag]
> -
> -
> -def is_new_val(regtype, regid, tag):
> -    return regtype + regid + "N" in semdict[tag]
> -
> -
>  def need_slot(tag):
>      if (
>          "A_CVI_SCATTER" not in attribdict[tag]
> @@ -280,14 +237,6 @@ def skip_qemu_helper(tag):
>      return tag in overrides.keys()
> 
> 
> -def is_tmp_result(tag):
> -    return "A_CVI_TMP" in attribdict[tag] or "A_CVI_TMP_DST" in
> attribdict[tag]
> -
> -
> -def is_new_result(tag):
> -    return "A_CVI_NEW" in attribdict[tag]
> -
> -
>  def is_idef_parser_enabled(tag):
>      return tag in idef_parser_enabled
> 
> --
> 2.34.1


Reviewed-by: Brian Cain <bcain@quicinc.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* RE: [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented
  2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
                   ` (8 preceding siblings ...)
  2023-12-10 22:07 ` [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions from hex_common.py Taylor Simpson
@ 2024-01-16  5:46 ` Brian Cain
  9 siblings, 0 replies; 19+ messages in thread
From: Brian Cain @ 2024-01-16  5:46 UTC (permalink / raw)
  To: Taylor Simpson, qemu-devel
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson, philmd, ale, anjo



> -----Original Message-----
> From: Taylor Simpson <ltaylorsimpson@gmail.com>
> Sent: Sunday, December 10, 2023 4:07 PM
> To: qemu-devel@nongnu.org
> Cc: Brian Cain <bcain@quicinc.com>; Matheus Bernardino (QUIC)
> <quic_mathbern@quicinc.com>; Sid Manning <sidneym@quicinc.com>; Marco
> Liebel (QUIC) <quic_mliebel@quicinc.com>; richard.henderson@linaro.org;
> philmd@linaro.org; ale@rev.ng; anjo@rev.ng; ltaylorsimpson@gmail.com
> Subject: [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object
> oriented
> 
> WARNING: This email originated from outside of Qualcomm. Please be wary of
> any links or attachments, and do not enable macros.
> 
> See commit message in second patch
> 
> **** Changes in v2 ****
> Address feedback from Brian Cain <bcain@quicinc.com>
> - Consolidate logic to create helper arg lists
> 
> 
> Taylor Simpson (9):
>   Hexagon (target/hexagon) Clean up handling of modifier registers
>   Hexagon (target/hexagon) Make generators object oriented -
>     gen_tcg_funcs
>   Hexagon (target/hexagon) Make generators object oriented -
>     gen_helper_protos
>   Hexagon (target/hexagon) Make generators object oriented -
>     gen_helper_funcs
>   Hexagon (target/hexagon) Make generators object oriented -
>     gen_idef_parser_funcs
>   Hexagon (target/hexagon) Make generators object oriented - gen_op_regs
>   Hexagon (target/hexagon) Make generators object oriented -
>     gen_analyze_funcs
>   Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute
>   Hexagon (target/hexagon) Remove dead functions from hex_common.py
> 
>  target/hexagon/gen_tcg.h                    |   9 +-
>  target/hexagon/macros.h                     |   3 +-
>  target/hexagon/attribs_def.h.inc            |   1 -
>  target/hexagon/idef-parser/parser-helpers.c |   8 +-
>  target/hexagon/gen_analyze_funcs.py         | 163 +---
>  target/hexagon/gen_helper_funcs.py          | 368 ++------
>  target/hexagon/gen_helper_protos.py         | 149 +---
>  target/hexagon/gen_idef_parser_funcs.py     |  20 +-
>  target/hexagon/gen_op_regs.py               |   6 +-
>  target/hexagon/gen_tcg_funcs.py             | 566 +-----------
>  target/hexagon/hex_common.py                | 921 ++++++++++++++++++--
>  11 files changed, 964 insertions(+), 1250 deletions(-)
> 
> --
> 2.34.1


Queued - https://github.com/quic/qemu/tree/hex.next

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2024-01-16  5:48 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-10 22:07 [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Taylor Simpson
2023-12-10 22:07 ` [PATCH v2 1/9] Hexagon (target/hexagon) Clean up handling of modifier registers Taylor Simpson
2023-12-10 22:07 ` [PATCH v2 2/9] Hexagon (target/hexagon) Make generators object oriented - gen_tcg_funcs Taylor Simpson
2024-01-11 21:08   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos Taylor Simpson
2024-01-11 21:08   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 4/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_funcs Taylor Simpson
2024-01-11 21:09   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 5/9] Hexagon (target/hexagon) Make generators object oriented - gen_idef_parser_funcs Taylor Simpson
2024-01-11 21:08   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 6/9] Hexagon (target/hexagon) Make generators object oriented - gen_op_regs Taylor Simpson
2024-01-11 21:09   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 7/9] Hexagon (target/hexagon) Make generators object oriented - gen_analyze_funcs Taylor Simpson
2024-01-11 21:09   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 8/9] Hexagon (target/hexagon) Remove unused WRITES_PRED_REG attribute Taylor Simpson
2024-01-11 21:09   ` Brian Cain
2023-12-10 22:07 ` [PATCH v2 9/9] Hexagon (target/hexagon) Remove dead functions from hex_common.py Taylor Simpson
2024-01-11 21:10   ` Brian Cain
2024-01-16  5:46 ` [PATCH v2 0/9] Hexagon (target/hexagon) Make generators object oriented Brian Cain

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.