qemu-devel.nongnu.org archive mirror
 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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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@nongnu.org
  Cc: Matheus Bernardino (QUIC), Sid Manning, Marco Liebel (QUIC),
	richard.henderson@linaro.org, philmd@linaro.org, ale@rev.ng,
	anjo@rev.ng



> -----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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).