@@ -75,7 +75,18 @@ def gen_tcg_func(f, tag, regs, imms):
arguments = ", ".join(["ctx", "ctx->insn", "ctx->pkt"] + declared)
f.write(f" emit_{tag}({arguments});\n")
+ elif hex_common.is_helper_to_tcg_enabled(tag) and tag.startswith("V6_"):
+ ## For vector functions translated by helper-to-tcg we need to
+ ## manually call the emitted code. All other instructions translated
+ ## are automatically called by the helper-functions dispatcher in
+ ## tcg_gen_callN.
+ declared = []
+ ## Handle registers
+ for arg in hex_common.helper_to_tcg_hvx_call_args(tag, regs, imms):
+ declared.append(arg)
+ arguments = ", ".join(declared)
+ f.write(f" emit_{tag}({arguments});\n")
elif hex_common.skip_qemu_helper(tag):
f.write(f" fGEN_TCG_{tag}({hex_common.semdict[tag]});\n")
else:
@@ -119,6 +130,8 @@ def main():
f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
if args.idef_parser:
f.write('#include "idef-generated-emitter.h.inc"\n\n')
+ if args.helper_to_tcg:
+ f.write('#include "helper-to-tcg-emitted.h"\n\n')
for tag in hex_common.tags:
## Skip the priv instructions
@@ -1105,6 +1105,60 @@ def helper_ret_type(tag, regs):
return return_type
+def helper_to_tcg_hvx_call_args(tag, regs, imms):
+ args = []
+ # Used to ensure immediates are passed translated as immediates by
+ # helper-to-tcg.
+ imm_indices = []
+
+ ## First argument is the CPU state
+ if need_env(tag):
+ args.append("tcg_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().call_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.hvx_off())
+
+ ## 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()):
+ if reg.is_hvx_reg():
+ args.append(reg.hvx_off())
+ else:
+ args.append(reg.helper_arg().call_arg)
+
+ ## Pass the immediates
+ for immlett, bits, immshift in imms:
+ imm_indices.append(len(args))
+ args.append(f"{imm_name(immlett)}")
+
+ ## Other stuff the helper might need
+ if need_pkt_has_multi_cof(tag):
+ args.append("ctx->pkt->pkt_has_multi_cof")
+ if need_pkt_need_commit(tag):
+ args.append("ctx->need_commit")
+ if need_PC(tag):
+ args.append("ctx->pkt->pc")
+ if need_next_PC(tag):
+ args.append("ctx->next_PC")
+ if need_slot(tag):
+ args.append("gen_slotval(ctx)")
+ if need_part1(tag):
+ args.append("insn->part1")
+
+ return args
+
+
def helper_args(tag, regs, imms):
args = []
# Used to ensure immediates are passed translated as immediates by
@@ -1216,12 +1270,15 @@ def parse_common_args(desc):
parser.add_argument("overrides_vec", help="vector overrides file")
parser.add_argument("out", help="output file")
parser.add_argument("--idef-parser", help="file of instructions translated by idef-parser")
+ parser.add_argument("--helper-to-tcg", help="file of instructions translated by helper-to-tcg")
args = parser.parse_args()
read_semantics_file(args.semantics)
read_overrides_file(args.overrides)
read_overrides_file(args.overrides_vec)
if args.idef_parser:
read_idef_parser_enabled_file(args.idef_parser)
+ if args.helper_to_tcg:
+ read_helper_to_tcg_enabled_file(args.helper_to_tcg)
calculate_attribs()
init_registers()
return args
For HVX instructions that were successfully translated by helper-to-tcg, emit calls to emit_*() "manually" from generate_*(). Recall that scalar instructions translated by helper-to-tcg are automatically called by a hook in tcg_gen_callN. Signed-off-by: Anton Johansson <anjo@rev.ng> --- target/hexagon/gen_tcg_funcs.py | 13 ++++++++ target/hexagon/hex_common.py | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+)