[PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos

Taylor Simpson posted 9 patches 11 months, 3 weeks ago
Maintainers: Brian Cain <bcain@quicinc.com>, Alessandro Di Federico <ale@rev.ng>, Anton Johansson <anjo@rev.ng>
[PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos
Posted by Taylor Simpson 11 months, 3 weeks ago
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
RE: [PATCH v2 3/9] Hexagon (target/hexagon) Make generators object oriented - gen_helper_protos
Posted by Brian Cain 10 months, 2 weeks ago

> -----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>