Short-circuit for packets with r/w and no overlap
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPWaq5HRZSCTIjOD4GlSvuOVkbDIFAmY4FR8ACgkQGlSvuOVk bDLEfxAAup6v9J4n2/q88FXfLGgx1EfZrT01gOM/48mwngNNQJGJQySe2GLl0G8S 1hx/Ym3jbikic8HL80v8FyCr4gNRshEY7xKpCfvY9lsgnCRbhEvoV/hZqucmLQAt 1SIhFSsi5h8gyZDTvXhH75v3qGvYjQ7fQBhy2JbRsPjthdHBh9xi6Na60wlqfNZq oGsVtY7sv1uHsvDKBi3JoXWckSK99R38BHY6zPoStarRZACkkLdX6KHxeX88TUt1 whIUYUS/K0nRVxzekdq/+m8UJYrXnW/0cliM5mLFHDGlsV+qjdcIRrfaPWBO0eFN kXeZU2BWLCdP2M52FHI4FllnIRpX5OGkxjR6x8Pc9r+EGciwGRU7xeAlqBxKQSZP e3oXtV6oKxg69xBgHE5HcKbt6bX5EZR/sUcbAoGA41UssaiMyj3wbg1cy2UxXu2J 7oJyywJUggWGSoCIIJJ95YgpUrIg73Yg6pOjfhKW1w/V2SuQPGG0XTXrwe7J6uGi VAqyu55p2oiW8Gk4Lvl1SfWgxkVeZa/NcxTmXNEWFnT7vatqwez0O5pxIkxdSCFE lRv7PuFT5nhQ/gg12zGqqRiOrMOMQitHFzJ9sUNu7J4Y7W5R4gzRW19ucojLt0lH fT83Ra+Eex1Cu3DsuvWkokxFikxXP1Ll297Jr1JhOPewTtvlxvI= =Q8/k -----END PGP SIGNATURE----- Merge tag 'pull-hex-20240505' of https://github.com/quic/qemu into staging Short-circuit for packets with r/w and no overlap # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEPWaq5HRZSCTIjOD4GlSvuOVkbDIFAmY4FR8ACgkQGlSvuOVk # bDLEfxAAup6v9J4n2/q88FXfLGgx1EfZrT01gOM/48mwngNNQJGJQySe2GLl0G8S # 1hx/Ym3jbikic8HL80v8FyCr4gNRshEY7xKpCfvY9lsgnCRbhEvoV/hZqucmLQAt # 1SIhFSsi5h8gyZDTvXhH75v3qGvYjQ7fQBhy2JbRsPjthdHBh9xi6Na60wlqfNZq # oGsVtY7sv1uHsvDKBi3JoXWckSK99R38BHY6zPoStarRZACkkLdX6KHxeX88TUt1 # whIUYUS/K0nRVxzekdq/+m8UJYrXnW/0cliM5mLFHDGlsV+qjdcIRrfaPWBO0eFN # kXeZU2BWLCdP2M52FHI4FllnIRpX5OGkxjR6x8Pc9r+EGciwGRU7xeAlqBxKQSZP # e3oXtV6oKxg69xBgHE5HcKbt6bX5EZR/sUcbAoGA41UssaiMyj3wbg1cy2UxXu2J # 7oJyywJUggWGSoCIIJJ95YgpUrIg73Yg6pOjfhKW1w/V2SuQPGG0XTXrwe7J6uGi # VAqyu55p2oiW8Gk4Lvl1SfWgxkVeZa/NcxTmXNEWFnT7vatqwez0O5pxIkxdSCFE # lRv7PuFT5nhQ/gg12zGqqRiOrMOMQitHFzJ9sUNu7J4Y7W5R4gzRW19ucojLt0lH # fT83Ra+Eex1Cu3DsuvWkokxFikxXP1Ll297Jr1JhOPewTtvlxvI= # =Q8/k # -----END PGP SIGNATURE----- # gpg: Signature made Sun 05 May 2024 04:24:15 PM PDT # gpg: using RSA key 3D66AAE474594824C88CE0F81A54AFB8E5646C32 # gpg: Good signature from "Brian Cain (QUIC) <quic_bcain@quicinc.com>" [unknown] # gpg: aka "Brian Cain <bcain@kernel.org>" [unknown] # gpg: aka "Brian Cain (QuIC) <bcain@quicinc.com>" [unknown] # gpg: aka "Brian Cain (CAF) <bcain@codeaurora.org>" [unknown] # gpg: aka "bcain" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6350 20F9 67A7 7164 79EF 49E0 175C 464E 541B 6D47 # Subkey fingerprint: 3D66 AAE4 7459 4824 C88C E0F8 1A54 AFB8 E564 6C32 * tag 'pull-hex-20240505' of https://github.com/quic/qemu: Hexagon (target/hexagon) Remove hex_common.read_attribs_file Hexagon (target/hexagon) Remove gen_shortcode.py Hexagon (target/hexagon) Remove gen_op_regs.py Hexagon (target/hexagon) Remove uses of op_regs_generated.h.inc Hexagon (tests/tcg/hexagon) Test HVX .new read from high half of pair Hexagon (target/hexagon) Mark has_pred_dest in trans functions Hexagon (target/hexagon) Mark dest_idx in trans functions Hexagon (target/hexagon) Mark new_read_idx in trans functions Hexagon (target/hexagon) Add is_old/is_new to Register class Hexagon (target/hexagon) Only pass env to generated helper when needed Hexagon (target/hexagon) Pass SP explicitly to helpers that need it Hexagon (target/hexagon) Pass P0 explicitly to helpers that need it Hexagon (target/hexagon) Enable more short-circuit packets (HVX) Hexagon (target/hexagon) Enable more short-circuit packets (scalar core) Hexagon (target/hexagon) Analyze reads before writes Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
28188253dc
@ -43,11 +43,9 @@ target/hexagon/gen_semantics.c. This step produces
|
|||||||
That file is consumed by the following python scripts to produce the indicated
|
That file is consumed by the following python scripts to produce the indicated
|
||||||
header files in <BUILD_DIR>/target/hexagon
|
header files in <BUILD_DIR>/target/hexagon
|
||||||
gen_opcodes_def.py -> opcodes_def_generated.h.inc
|
gen_opcodes_def.py -> opcodes_def_generated.h.inc
|
||||||
gen_op_regs.py -> op_regs_generated.h.inc
|
|
||||||
gen_printinsn.py -> printinsn_generated.h.inc
|
gen_printinsn.py -> printinsn_generated.h.inc
|
||||||
gen_op_attribs.py -> op_attribs_generated.h.inc
|
gen_op_attribs.py -> op_attribs_generated.h.inc
|
||||||
gen_helper_protos.py -> helper_protos_generated.h.inc
|
gen_helper_protos.py -> helper_protos_generated.h.inc
|
||||||
gen_shortcode.py -> shortcode_generated.h.inc
|
|
||||||
gen_tcg_funcs.py -> tcg_funcs_generated.c.inc
|
gen_tcg_funcs.py -> tcg_funcs_generated.c.inc
|
||||||
gen_tcg_func_table.py -> tcg_func_table_generated.c.inc
|
gen_tcg_func_table.py -> tcg_func_table_generated.c.inc
|
||||||
gen_helper_funcs.py -> helper_funcs_generated.c.inc
|
gen_helper_funcs.py -> helper_funcs_generated.c.inc
|
||||||
@ -183,10 +181,11 @@ when the override is present.
|
|||||||
}
|
}
|
||||||
|
|
||||||
We also generate an analyze_<tag> function for each instruction. Currently,
|
We also generate an analyze_<tag> function for each instruction. Currently,
|
||||||
these functions record the writes to registers by calling ctx_log_*. During
|
these functions record the reads and writes to registers by calling ctx_log_*.
|
||||||
gen_start_packet, we invoke the analyze_<tag> function for each instruction in
|
During gen_start_packet, we invoke the analyze_<tag> function for each instruction in
|
||||||
the packet, and we mark the implicit writes. After the analysis is performed,
|
the packet, and we mark the implicit writes. The analysis determines if the packet
|
||||||
we initialize the result register for each of the predicated assignments.
|
semantics can be short-circuited. If not, we initialize the result register for each
|
||||||
|
of the predicated assignments.
|
||||||
|
|
||||||
In addition to instruction semantics, we use a generator to create the decode
|
In addition to instruction semantics, we use a generator to create the decode
|
||||||
tree. This generation is a four step process.
|
tree. This generation is a four step process.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -117,6 +117,7 @@ DEF_ATTRIB(IMPLICIT_READS_P1, "Reads the P1 register", "", "")
|
|||||||
DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
|
DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
|
||||||
DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
|
DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
|
||||||
DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
|
DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
|
||||||
|
DEF_ATTRIB(IMPLICIT_READS_SP, "Reads the SP register", "", "")
|
||||||
DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
|
DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
|
||||||
DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
|
DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
|
||||||
DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
|
DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
|
||||||
|
@ -115,22 +115,13 @@ static void
|
|||||||
decode_fill_newvalue_regno(Packet *packet)
|
decode_fill_newvalue_regno(Packet *packet)
|
||||||
{
|
{
|
||||||
int i, use_regidx, offset, def_idx, dst_idx;
|
int i, use_regidx, offset, def_idx, dst_idx;
|
||||||
uint16_t def_opcode, use_opcode;
|
|
||||||
char *dststr;
|
|
||||||
|
|
||||||
for (i = 1; i < packet->num_insns; i++) {
|
for (i = 1; i < packet->num_insns; i++) {
|
||||||
if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE) &&
|
if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE) &&
|
||||||
!GET_ATTRIB(packet->insn[i].opcode, A_EXTENSION)) {
|
!GET_ATTRIB(packet->insn[i].opcode, A_EXTENSION)) {
|
||||||
use_opcode = packet->insn[i].opcode;
|
|
||||||
|
|
||||||
/* It's a store, so we're adjusting the Nt field */
|
g_assert(packet->insn[i].new_read_idx != -1);
|
||||||
if (GET_ATTRIB(use_opcode, A_STORE)) {
|
use_regidx = packet->insn[i].new_read_idx;
|
||||||
use_regidx = strchr(opcode_reginfo[use_opcode], 't') -
|
|
||||||
opcode_reginfo[use_opcode];
|
|
||||||
} else { /* It's a Jump, so we're adjusting the Ns field */
|
|
||||||
use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
|
|
||||||
opcode_reginfo[use_opcode];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* What's encoded at the N-field is the offset to who's producing
|
* What's encoded at the N-field is the offset to who's producing
|
||||||
@ -151,37 +142,9 @@ decode_fill_newvalue_regno(Packet *packet)
|
|||||||
*/
|
*/
|
||||||
g_assert(!((def_idx < 0) || (def_idx > (packet->num_insns - 1))));
|
g_assert(!((def_idx < 0) || (def_idx > (packet->num_insns - 1))));
|
||||||
|
|
||||||
/*
|
|
||||||
* packet->insn[def_idx] is the producer
|
|
||||||
* Figure out which type of destination it produces
|
|
||||||
* and the corresponding index in the reginfo
|
|
||||||
*/
|
|
||||||
def_opcode = packet->insn[def_idx].opcode;
|
|
||||||
dststr = strstr(opcode_wregs[def_opcode], "Rd");
|
|
||||||
if (dststr) {
|
|
||||||
dststr = strchr(opcode_reginfo[def_opcode], 'd');
|
|
||||||
} else {
|
|
||||||
dststr = strstr(opcode_wregs[def_opcode], "Rx");
|
|
||||||
if (dststr) {
|
|
||||||
dststr = strchr(opcode_reginfo[def_opcode], 'x');
|
|
||||||
} else {
|
|
||||||
dststr = strstr(opcode_wregs[def_opcode], "Re");
|
|
||||||
if (dststr) {
|
|
||||||
dststr = strchr(opcode_reginfo[def_opcode], 'e');
|
|
||||||
} else {
|
|
||||||
dststr = strstr(opcode_wregs[def_opcode], "Ry");
|
|
||||||
if (dststr) {
|
|
||||||
dststr = strchr(opcode_reginfo[def_opcode], 'y');
|
|
||||||
} else {
|
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_assert(dststr != NULL);
|
|
||||||
|
|
||||||
/* Now patch up the consumer with the register number */
|
/* Now patch up the consumer with the register number */
|
||||||
dst_idx = dststr - opcode_reginfo[def_opcode];
|
g_assert(packet->insn[def_idx].dest_idx != -1);
|
||||||
|
dst_idx = packet->insn[def_idx].dest_idx;
|
||||||
packet->insn[i].regno[use_regidx] =
|
packet->insn[i].regno[use_regidx] =
|
||||||
packet->insn[def_idx].regno[dst_idx];
|
packet->insn[def_idx].regno[dst_idx];
|
||||||
/*
|
/*
|
||||||
@ -362,8 +325,7 @@ static void decode_shuffle_for_execution(Packet *packet)
|
|||||||
for (flag = false, i = 0; i < last_insn + 1; i++) {
|
for (flag = false, i = 0; i < last_insn + 1; i++) {
|
||||||
int opcode = packet->insn[i].opcode;
|
int opcode = packet->insn[i].opcode;
|
||||||
|
|
||||||
if ((strstr(opcode_wregs[opcode], "Pd4") ||
|
if (packet->insn[i].has_pred_dest &&
|
||||||
strstr(opcode_wregs[opcode], "Pe4")) &&
|
|
||||||
GET_ATTRIB(opcode, A_STORE) == 0) {
|
GET_ATTRIB(opcode, A_STORE) == 0) {
|
||||||
/* This should be a compare (not a store conditional) */
|
/* This should be a compare (not a store conditional) */
|
||||||
if (flag) {
|
if (flag) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2022-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -43,59 +43,53 @@ def gen_analyze_func(f, tag, regs, imms):
|
|||||||
f.write("{\n")
|
f.write("{\n")
|
||||||
|
|
||||||
f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
|
f.write(" Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
|
||||||
|
if (hex_common.is_hvx_insn(tag)):
|
||||||
i = 0
|
if hex_common.has_hvx_helper(tag):
|
||||||
## Analyze all the registers
|
f.write(
|
||||||
for regtype, regid in regs:
|
" const bool G_GNUC_UNUSED insn_has_hvx_helper = true;\n"
|
||||||
reg = hex_common.get_register(tag, regtype, regid)
|
)
|
||||||
if reg.is_written():
|
f.write(" ctx_start_hvx_insn(ctx);\n")
|
||||||
reg.analyze_write(f, tag, i)
|
|
||||||
else:
|
else:
|
||||||
reg.analyze_read(f, i)
|
f.write(
|
||||||
i += 1
|
" const bool G_GNUC_UNUSED insn_has_hvx_helper = false;\n"
|
||||||
|
)
|
||||||
|
|
||||||
has_generated_helper = not hex_common.skip_qemu_helper(
|
## Declare all the registers
|
||||||
tag
|
for regno, register in enumerate(regs):
|
||||||
) and not hex_common.is_idef_parser_enabled(tag)
|
reg_type, reg_id = register
|
||||||
|
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||||
|
reg.decl_reg_num(f, regno)
|
||||||
|
|
||||||
## Mark HVX instructions with generated helpers
|
## Analyze the register reads
|
||||||
if (has_generated_helper and
|
for regno, register in enumerate(regs):
|
||||||
"A_CVI" in hex_common.attribdict[tag]):
|
reg_type, reg_id = register
|
||||||
f.write(" ctx->has_hvx_helper = true;\n")
|
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||||
|
if reg.is_read():
|
||||||
|
reg.analyze_read(f, regno)
|
||||||
|
|
||||||
|
## Analyze the register writes
|
||||||
|
for regno, register in enumerate(regs):
|
||||||
|
reg_type, reg_id = register
|
||||||
|
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||||
|
if reg.is_written():
|
||||||
|
reg.analyze_write(f, tag, regno)
|
||||||
|
|
||||||
f.write("}\n\n")
|
f.write("}\n\n")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_common_files()
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.read_overrides_file(sys.argv[3])
|
|
||||||
hex_common.read_overrides_file(sys.argv[4])
|
|
||||||
## Whether or not idef-parser is enabled is
|
|
||||||
## determined by the number of arguments to
|
|
||||||
## this script:
|
|
||||||
##
|
|
||||||
## 5 args. -> not enabled,
|
|
||||||
## 6 args. -> idef-parser enabled.
|
|
||||||
##
|
|
||||||
## The 6:th arg. then holds a list of the successfully
|
|
||||||
## parsed instructions.
|
|
||||||
is_idef_parser_enabled = len(sys.argv) > 6
|
|
||||||
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()
|
tagregs = hex_common.get_tagregs()
|
||||||
tagimms = hex_common.get_tagimms()
|
tagimms = hex_common.get_tagimms()
|
||||||
|
|
||||||
with open(sys.argv[-1], "w") as f:
|
with open(sys.argv[-1], "w") as f:
|
||||||
f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
|
f.write("#ifndef HEXAGON_ANALYZE_FUNCS_C_INC\n")
|
||||||
f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
|
f.write("#define HEXAGON_ANALYZE_FUNCS_C_INC\n\n")
|
||||||
|
|
||||||
for tag in hex_common.tags:
|
for tag in hex_common.tags:
|
||||||
gen_analyze_func(f, tag, tagregs[tag], tagimms[tag])
|
gen_analyze_func(f, tag, tagregs[tag], tagimms[tag])
|
||||||
|
|
||||||
f.write("#endif /* HEXAGON_TCG_FUNCS_H */\n")
|
f.write("#endif /* HEXAGON_ANALYZE_FUNCS_C_INC */\n")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -102,24 +102,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_common_files()
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.read_overrides_file(sys.argv[3])
|
|
||||||
hex_common.read_overrides_file(sys.argv[4])
|
|
||||||
## Whether or not idef-parser is enabled is
|
|
||||||
## determined by the number of arguments to
|
|
||||||
## this script:
|
|
||||||
##
|
|
||||||
## 5 args. -> not enabled,
|
|
||||||
## 6 args. -> idef-parser enabled.
|
|
||||||
##
|
|
||||||
## The 6:th arg. then holds a list of the successfully
|
|
||||||
## parsed instructions.
|
|
||||||
is_idef_parser_enabled = len(sys.argv) > 6
|
|
||||||
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()
|
tagregs = hex_common.get_tagregs()
|
||||||
tagimms = hex_common.get_tagimms()
|
tagimms = hex_common.get_tagimms()
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -40,28 +40,19 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
|
|||||||
declared.append(arg.proto_arg)
|
declared.append(arg.proto_arg)
|
||||||
|
|
||||||
arguments = ", ".join(declared)
|
arguments = ", ".join(declared)
|
||||||
f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
|
|
||||||
|
## Add the TCG_CALL_NO_RWG_SE flag to helpers that don't take the env
|
||||||
|
## argument and aren't HVX instructions. Since HVX instructions take
|
||||||
|
## pointers to their arguments, they will have side effects.
|
||||||
|
if hex_common.need_env(tag) or hex_common.is_hvx_insn(tag):
|
||||||
|
f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
|
||||||
|
else:
|
||||||
|
f.write(f"DEF_HELPER_FLAGS_{len(declared) - 1}({tag}, "
|
||||||
|
f"TCG_CALL_NO_RWG_SE, {arguments})\n")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_common_files()
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.read_overrides_file(sys.argv[3])
|
|
||||||
hex_common.read_overrides_file(sys.argv[4])
|
|
||||||
## Whether or not idef-parser is enabled is
|
|
||||||
## determined by the number of arguments to
|
|
||||||
## this script:
|
|
||||||
##
|
|
||||||
## 5 args. -> not enabled,
|
|
||||||
## 6 args. -> idef-parser enabled.
|
|
||||||
##
|
|
||||||
## The 6:th arg. then holds a list of the successfully
|
|
||||||
## parsed instructions.
|
|
||||||
is_idef_parser_enabled = len(sys.argv) > 6
|
|
||||||
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()
|
tagregs = hex_common.get_tagregs()
|
||||||
tagimms = hex_common.get_tagimms()
|
tagimms = hex_common.get_tagimms()
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 rev.ng Labs Srl. All Rights Reserved.
|
## Copyright(c) 2019-2024 rev.ng Labs Srl. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -44,13 +44,12 @@ import hex_common
|
|||||||
##
|
##
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_semantics_file(sys.argv[1])
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.calculate_attribs()
|
hex_common.calculate_attribs()
|
||||||
hex_common.init_registers()
|
hex_common.init_registers()
|
||||||
tagregs = hex_common.get_tagregs()
|
tagregs = hex_common.get_tagregs()
|
||||||
tagimms = hex_common.get_tagimms()
|
tagimms = hex_common.get_tagimms()
|
||||||
|
|
||||||
with open(sys.argv[3], "w") as f:
|
with open(sys.argv[-1], "w") as f:
|
||||||
f.write('#include "macros.inc"\n\n')
|
f.write('#include "macros.inc"\n\n')
|
||||||
|
|
||||||
for tag in hex_common.tags:
|
for tag in hex_common.tags:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -25,13 +25,12 @@ import hex_common
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_semantics_file(sys.argv[1])
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.calculate_attribs()
|
hex_common.calculate_attribs()
|
||||||
|
|
||||||
##
|
##
|
||||||
## Generate all the attributes associated with each instruction
|
## Generate all the attributes associated with each instruction
|
||||||
##
|
##
|
||||||
with open(sys.argv[3], "w") as f:
|
with open(sys.argv[-1], "w") as f:
|
||||||
for tag in hex_common.tags:
|
for tag in hex_common.tags:
|
||||||
f.write(
|
f.write(
|
||||||
f"OP_ATTRIB({tag},ATTRIBS("
|
f"OP_ATTRIB({tag},ATTRIBS("
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
##
|
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
|
||||||
##
|
|
||||||
## This program is free software; you can redistribute it and/or modify
|
|
||||||
## it under the terms of the GNU General Public License as published by
|
|
||||||
## the Free Software Foundation; either version 2 of the License, or
|
|
||||||
## (at your option) any later version.
|
|
||||||
##
|
|
||||||
## This program is distributed in the hope that it will be useful,
|
|
||||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
## GNU General Public License for more details.
|
|
||||||
##
|
|
||||||
## You should have received a copy of the GNU General Public License
|
|
||||||
## along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
##
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
import hex_common
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
## Generate the register and immediate operands for each instruction
|
|
||||||
##
|
|
||||||
def calculate_regid_reg(tag):
|
|
||||||
def letter_inc(x):
|
|
||||||
return chr(ord(x) + 1)
|
|
||||||
|
|
||||||
ordered_implregs = ["SP", "FP", "LR"]
|
|
||||||
srcdst_lett = "X"
|
|
||||||
src_lett = "S"
|
|
||||||
dst_lett = "D"
|
|
||||||
retstr = ""
|
|
||||||
mapdict = {}
|
|
||||||
for reg in ordered_implregs:
|
|
||||||
reg_rd = 0
|
|
||||||
reg_wr = 0
|
|
||||||
if ("A_IMPLICIT_WRITES_" + reg) in hex_common.attribdict[tag]:
|
|
||||||
reg_wr = 1
|
|
||||||
if reg_rd and reg_wr:
|
|
||||||
retstr += srcdst_lett
|
|
||||||
mapdict[srcdst_lett] = reg
|
|
||||||
srcdst_lett = letter_inc(srcdst_lett)
|
|
||||||
elif reg_rd:
|
|
||||||
retstr += src_lett
|
|
||||||
mapdict[src_lett] = reg
|
|
||||||
src_lett = letter_inc(src_lett)
|
|
||||||
elif reg_wr:
|
|
||||||
retstr += dst_lett
|
|
||||||
mapdict[dst_lett] = reg
|
|
||||||
dst_lett = letter_inc(dst_lett)
|
|
||||||
return retstr, mapdict
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_regid_letters(tag):
|
|
||||||
retstr, mapdict = calculate_regid_reg(tag)
|
|
||||||
return retstr
|
|
||||||
|
|
||||||
|
|
||||||
def strip_reg_prefix(x):
|
|
||||||
y = x.replace("UREG.", "")
|
|
||||||
y = y.replace("MREG.", "")
|
|
||||||
return y.replace("GREG.", "")
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
with open(sys.argv[3], "w") as f:
|
|
||||||
for tag in hex_common.tags:
|
|
||||||
regs = tagregs[tag]
|
|
||||||
rregs = []
|
|
||||||
wregs = []
|
|
||||||
regids = ""
|
|
||||||
for regtype, regid, _, numregs in regs:
|
|
||||||
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 reg.is_written():
|
|
||||||
wregs.append(regtype + regid + numregs)
|
|
||||||
if regid[0] not in regids:
|
|
||||||
regids += regid[0]
|
|
||||||
for attrib in hex_common.attribdict[tag]:
|
|
||||||
if hex_common.attribinfo[attrib]["rreg"]:
|
|
||||||
rregs.append(strip_reg_prefix(attribinfo[attrib]["rreg"]))
|
|
||||||
if hex_common.attribinfo[attrib]["wreg"]:
|
|
||||||
wregs.append(strip_reg_prefix(attribinfo[attrib]["wreg"]))
|
|
||||||
regids += calculate_regid_letters(tag)
|
|
||||||
f.write(
|
|
||||||
f'REGINFO({tag},"{regids}",\t/*RD:*/\t"{",".join(rregs)}",'
|
|
||||||
f'\t/*WR:*/\t"{",".join(wregs)}")\n'
|
|
||||||
)
|
|
||||||
|
|
||||||
for tag in hex_common.tags:
|
|
||||||
imms = tagimms[tag]
|
|
||||||
f.write(f"IMMINFO({tag}")
|
|
||||||
if not imms:
|
|
||||||
f.write(""",'u',0,0,'U',0,0""")
|
|
||||||
for sign, size, shamt in imms:
|
|
||||||
if sign == "r":
|
|
||||||
sign = "s"
|
|
||||||
if not shamt:
|
|
||||||
shamt = "0"
|
|
||||||
f.write(f""",'{sign}',{size},{shamt}""")
|
|
||||||
if len(imms) == 1:
|
|
||||||
if sign.isupper():
|
|
||||||
myu = "u"
|
|
||||||
else:
|
|
||||||
myu = "U"
|
|
||||||
f.write(f""",'{myu}',0,0""")
|
|
||||||
f.write(")\n")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -29,7 +29,7 @@ def main():
|
|||||||
##
|
##
|
||||||
## Generate a list of all the opcodes
|
## Generate a list of all the opcodes
|
||||||
##
|
##
|
||||||
with open(sys.argv[3], "w") as f:
|
with open(sys.argv[-1], "w") as f:
|
||||||
for tag in hex_common.tags:
|
for tag in hex_common.tags:
|
||||||
f.write(f"OPCODE({tag}),\n")
|
f.write(f"OPCODE({tag}),\n")
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -97,11 +97,10 @@ def spacify(s):
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_semantics_file(sys.argv[1])
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
|
|
||||||
immext_casere = re.compile(r"IMMEXT\(([A-Za-z])")
|
immext_casere = re.compile(r"IMMEXT\(([A-Za-z])")
|
||||||
|
|
||||||
with open(sys.argv[3], "w") as f:
|
with open(sys.argv[-1], "w") as f:
|
||||||
for tag in hex_common.tags:
|
for tag in hex_common.tags:
|
||||||
if not hex_common.behdict[tag]:
|
if not hex_common.behdict[tag]:
|
||||||
continue
|
continue
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
##
|
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
|
||||||
##
|
|
||||||
## This program is free software; you can redistribute it and/or modify
|
|
||||||
## it under the terms of the GNU General Public License as published by
|
|
||||||
## the Free Software Foundation; either version 2 of the License, or
|
|
||||||
## (at your option) any later version.
|
|
||||||
##
|
|
||||||
## This program is distributed in the hope that it will be useful,
|
|
||||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
## GNU General Public License for more details.
|
|
||||||
##
|
|
||||||
## You should have received a copy of the GNU General Public License
|
|
||||||
## along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
||||||
##
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
import hex_common
|
|
||||||
|
|
||||||
|
|
||||||
def gen_shortcode(f, tag):
|
|
||||||
f.write(f"DEF_SHORTCODE({tag}, {hex_common.semdict[tag]})\n")
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.calculate_attribs()
|
|
||||||
tagregs = hex_common.get_tagregs()
|
|
||||||
tagimms = hex_common.get_tagimms()
|
|
||||||
|
|
||||||
with open(sys.argv[3], "w") as f:
|
|
||||||
f.write("#ifndef DEF_SHORTCODE\n")
|
|
||||||
f.write("#define DEF_SHORTCODE(TAG,SHORTCODE) /* Nothing */\n")
|
|
||||||
f.write("#endif\n")
|
|
||||||
|
|
||||||
for tag in hex_common.tags:
|
|
||||||
## Skip the priv instructions
|
|
||||||
if "A_PRIV" in hex_common.attribdict[tag]:
|
|
||||||
continue
|
|
||||||
## Skip the guest instructions
|
|
||||||
if "A_GUEST" in hex_common.attribdict[tag]:
|
|
||||||
continue
|
|
||||||
## Skip the diag instructions
|
|
||||||
if tag == "Y6_diag":
|
|
||||||
continue
|
|
||||||
if tag == "Y6_diag0":
|
|
||||||
continue
|
|
||||||
if tag == "Y6_diag1":
|
|
||||||
continue
|
|
||||||
|
|
||||||
gen_shortcode(f, tag)
|
|
||||||
|
|
||||||
f.write("#undef DEF_SHORTCODE\n")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -1369,3 +1369,6 @@
|
|||||||
gen_helper_raise_exception(tcg_env, excp); \
|
gen_helper_raise_exception(tcg_env, excp); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define fGEN_TCG_A2_nop(SHORTCODE) do { } while (0)
|
||||||
|
#define fGEN_TCG_SA1_setin1(SHORTCODE) tcg_gen_movi_tl(RdV, -1)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -25,12 +25,11 @@ import hex_common
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_semantics_file(sys.argv[1])
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
hex_common.calculate_attribs()
|
hex_common.calculate_attribs()
|
||||||
tagregs = hex_common.get_tagregs()
|
tagregs = hex_common.get_tagregs()
|
||||||
tagimms = hex_common.get_tagimms()
|
tagimms = hex_common.get_tagimms()
|
||||||
|
|
||||||
with open(sys.argv[3], "w") as f:
|
with open(sys.argv[-1], "w") as f:
|
||||||
f.write("#ifndef HEXAGON_FUNC_TABLE_H\n")
|
f.write("#ifndef HEXAGON_FUNC_TABLE_H\n")
|
||||||
f.write("#define HEXAGON_FUNC_TABLE_H\n\n")
|
f.write("#define HEXAGON_FUNC_TABLE_H\n\n")
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -108,24 +108,7 @@ def gen_def_tcg_func(f, tag, tagregs, tagimms):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
is_idef_parser_enabled = hex_common.read_common_files()
|
||||||
hex_common.read_attribs_file(sys.argv[2])
|
|
||||||
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:
|
|
||||||
##
|
|
||||||
## 5 args. -> not enabled,
|
|
||||||
## 6 args. -> idef-parser enabled.
|
|
||||||
##
|
|
||||||
## The 6:th arg. then holds a list of the successfully
|
|
||||||
## parsed instructions.
|
|
||||||
is_idef_parser_enabled = len(sys.argv) > 6
|
|
||||||
if is_idef_parser_enabled:
|
|
||||||
hex_common.read_idef_parser_enabled_file(sys.argv[5])
|
|
||||||
tagregs = hex_common.get_tagregs()
|
tagregs = hex_common.get_tagregs()
|
||||||
tagimms = hex_common.get_tagimms()
|
tagimms = hex_common.get_tagimms()
|
||||||
|
|
||||||
|
@ -68,6 +68,9 @@ def mark_which_imm_extended(f, tag):
|
|||||||
## insn->regno[0] = args->Rd;
|
## insn->regno[0] = args->Rd;
|
||||||
## insn->regno[1] = args->Rs;
|
## insn->regno[1] = args->Rs;
|
||||||
## insn->regno[2] = args->Rt;
|
## insn->regno[2] = args->Rt;
|
||||||
|
## insn->new_read_idx = -1;
|
||||||
|
## insn->dest_idx = 0;
|
||||||
|
## insn->has_pred_dest = false;
|
||||||
## return true;
|
## return true;
|
||||||
## }
|
## }
|
||||||
##
|
##
|
||||||
@ -84,14 +87,21 @@ def gen_trans_funcs(f):
|
|||||||
insn->opcode = {tag};
|
insn->opcode = {tag};
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
regno = 0
|
new_read_idx = -1
|
||||||
for reg in regs:
|
dest_idx = -1
|
||||||
reg_type = reg[0]
|
has_pred_dest = "false"
|
||||||
reg_id = reg[1]
|
for regno, (reg_type, reg_id, *_) in enumerate(regs):
|
||||||
|
reg = hex_common.get_register(tag, reg_type, reg_id)
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
insn->regno[{regno}] = args->{reg_type}{reg_id};
|
insn->regno[{regno}] = args->{reg_type}{reg_id};
|
||||||
"""))
|
"""))
|
||||||
regno += 1
|
if reg.is_read() and reg.is_new():
|
||||||
|
new_read_idx = regno
|
||||||
|
# dest_idx should be the first destination, so check for -1
|
||||||
|
if reg.is_written() and dest_idx == -1:
|
||||||
|
dest_idx = regno
|
||||||
|
if reg_type == "P" and reg.is_written() and not reg.is_read():
|
||||||
|
has_pred_dest = "true"
|
||||||
|
|
||||||
if len(imms) != 0:
|
if len(imms) != 0:
|
||||||
mark_which_imm_extended(f, tag)
|
mark_which_imm_extended(f, tag)
|
||||||
@ -112,6 +122,11 @@ def gen_trans_funcs(f):
|
|||||||
insn->immed[{immno}] = args->{imm_type}{imm_letter};
|
insn->immed[{immno}] = args->{imm_type}{imm_letter};
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
insn->new_read_idx = {new_read_idx};
|
||||||
|
insn->dest_idx = {dest_idx};
|
||||||
|
insn->has_pred_dest = {has_pred_dest};
|
||||||
|
"""))
|
||||||
f.write(textwrap.dedent(f"""\
|
f.write(textwrap.dedent(f"""\
|
||||||
return true;
|
return true;
|
||||||
{close_curly}
|
{close_curly}
|
||||||
@ -120,5 +135,6 @@ def gen_trans_funcs(f):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
hex_common.read_semantics_file(sys.argv[1])
|
hex_common.read_semantics_file(sys.argv[1])
|
||||||
|
hex_common.init_registers()
|
||||||
with open(sys.argv[2], "w") as f:
|
with open(sys.argv[2], "w") as f:
|
||||||
gen_trans_funcs(f)
|
gen_trans_funcs(f)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
##
|
##
|
||||||
## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -26,7 +26,6 @@ behdict = {} # tag ->behavior
|
|||||||
semdict = {} # tag -> semantics
|
semdict = {} # tag -> semantics
|
||||||
attribdict = {} # tag -> attributes
|
attribdict = {} # tag -> attributes
|
||||||
macros = {} # macro -> macro information...
|
macros = {} # macro -> macro information...
|
||||||
attribinfo = {} # Register information and misc
|
|
||||||
registers = {} # register -> register functions
|
registers = {} # register -> register functions
|
||||||
new_registers = {}
|
new_registers = {}
|
||||||
tags = [] # list of all tags
|
tags = [] # list of all tags
|
||||||
@ -101,6 +100,7 @@ def calculate_attribs():
|
|||||||
add_qemu_macro_attrib('fLSBNEW1', 'A_IMPLICIT_READS_P1')
|
add_qemu_macro_attrib('fLSBNEW1', 'A_IMPLICIT_READS_P1')
|
||||||
add_qemu_macro_attrib('fLSBNEW1NOT', 'A_IMPLICIT_READS_P1')
|
add_qemu_macro_attrib('fLSBNEW1NOT', 'A_IMPLICIT_READS_P1')
|
||||||
add_qemu_macro_attrib('fREAD_P3', 'A_IMPLICIT_READS_P3')
|
add_qemu_macro_attrib('fREAD_P3', 'A_IMPLICIT_READS_P3')
|
||||||
|
add_qemu_macro_attrib('fREAD_SP', 'A_IMPLICIT_READS_SP')
|
||||||
|
|
||||||
# Recurse down macros, find attributes from sub-macros
|
# Recurse down macros, find attributes from sub-macros
|
||||||
macroValues = list(macros.values())
|
macroValues = list(macros.values())
|
||||||
@ -197,6 +197,26 @@ def get_tagimms():
|
|||||||
return dict(zip(tags, list(map(compute_tag_immediates, tags))))
|
return dict(zip(tags, list(map(compute_tag_immediates, tags))))
|
||||||
|
|
||||||
|
|
||||||
|
def need_p0(tag):
|
||||||
|
return "A_IMPLICIT_READS_P0" in attribdict[tag]
|
||||||
|
|
||||||
|
|
||||||
|
def need_sp(tag):
|
||||||
|
return "A_IMPLICIT_READS_SP" in attribdict[tag]
|
||||||
|
|
||||||
|
|
||||||
|
def is_hvx_insn(tag):
|
||||||
|
return "A_CVI" in attribdict[tag]
|
||||||
|
|
||||||
|
|
||||||
|
def need_env(tag):
|
||||||
|
return ("A_STORE" in attribdict[tag] or
|
||||||
|
"A_LOAD" in attribdict[tag] or
|
||||||
|
"A_CVI_GATHER" in attribdict[tag] or
|
||||||
|
"A_CVI_SCATTER" in attribdict[tag] or
|
||||||
|
"A_IMPLICIT_WRITES_USR" in attribdict[tag])
|
||||||
|
|
||||||
|
|
||||||
def need_slot(tag):
|
def need_slot(tag):
|
||||||
if (
|
if (
|
||||||
"A_CVI_SCATTER" not in attribdict[tag]
|
"A_CVI_SCATTER" not in attribdict[tag]
|
||||||
@ -241,6 +261,16 @@ def is_idef_parser_enabled(tag):
|
|||||||
return tag in idef_parser_enabled
|
return tag in idef_parser_enabled
|
||||||
|
|
||||||
|
|
||||||
|
def is_hvx_insn(tag):
|
||||||
|
return "A_CVI" in attribdict[tag]
|
||||||
|
|
||||||
|
|
||||||
|
def has_hvx_helper(tag):
|
||||||
|
return (is_hvx_insn(tag) and
|
||||||
|
not skip_qemu_helper(tag) and
|
||||||
|
not is_idef_parser_enabled(tag))
|
||||||
|
|
||||||
|
|
||||||
def imm_name(immlett):
|
def imm_name(immlett):
|
||||||
return f"{immlett}iV"
|
return f"{immlett}iV"
|
||||||
|
|
||||||
@ -257,19 +287,6 @@ def read_semantics_file(name):
|
|||||||
eval_line = ""
|
eval_line = ""
|
||||||
|
|
||||||
|
|
||||||
def read_attribs_file(name):
|
|
||||||
attribre = re.compile(
|
|
||||||
r"DEF_ATTRIB\(([A-Za-z0-9_]+), ([^,]*), "
|
|
||||||
+ r'"([A-Za-z0-9_\.]*)", "([A-Za-z0-9_\.]*)"\)'
|
|
||||||
)
|
|
||||||
for line in open(name, "rt").readlines():
|
|
||||||
if not attribre.match(line):
|
|
||||||
continue
|
|
||||||
(attrib_base, descr, rreg, wreg) = attribre.findall(line)[0]
|
|
||||||
attrib_base = "A_" + attrib_base
|
|
||||||
attribinfo[attrib_base] = {"rreg": rreg, "wreg": wreg, "descr": descr}
|
|
||||||
|
|
||||||
|
|
||||||
def read_overrides_file(name):
|
def read_overrides_file(name):
|
||||||
overridere = re.compile(r"#define fGEN_TCG_([A-Za-z0-9_]+)\(.*")
|
overridere = re.compile(r"#define fGEN_TCG_([A-Za-z0-9_]+)\(.*")
|
||||||
for line in open(name, "rt").readlines():
|
for line in open(name, "rt").readlines():
|
||||||
@ -397,10 +414,18 @@ class Source:
|
|||||||
class OldSource(Source):
|
class OldSource(Source):
|
||||||
def reg_tcg(self):
|
def reg_tcg(self):
|
||||||
return f"{self.regtype}{self.regid}V"
|
return f"{self.regtype}{self.regid}V"
|
||||||
|
def is_old(self):
|
||||||
|
return True
|
||||||
|
def is_new(self):
|
||||||
|
return False
|
||||||
|
|
||||||
class NewSource(Source):
|
class NewSource(Source):
|
||||||
def reg_tcg(self):
|
def reg_tcg(self):
|
||||||
return f"{self.regtype}{self.regid}N"
|
return f"{self.regtype}{self.regid}N"
|
||||||
|
def is_old(self):
|
||||||
|
return False
|
||||||
|
def is_new(self):
|
||||||
|
return True
|
||||||
|
|
||||||
class ReadWrite:
|
class ReadWrite:
|
||||||
def reg_tcg(self):
|
def reg_tcg(self):
|
||||||
@ -413,6 +438,10 @@ class ReadWrite:
|
|||||||
return True
|
return True
|
||||||
def is_readwrite(self):
|
def is_readwrite(self):
|
||||||
return True
|
return True
|
||||||
|
def is_old(self):
|
||||||
|
return True
|
||||||
|
def is_new(self):
|
||||||
|
return False
|
||||||
|
|
||||||
class GprDest(Register, Single, Dest):
|
class GprDest(Register, Single, Dest):
|
||||||
def decl_tcg(self, f, tag, regno):
|
def decl_tcg(self, f, tag, regno):
|
||||||
@ -425,7 +454,6 @@ class GprDest(Register, Single, Dest):
|
|||||||
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
||||||
@ -438,7 +466,6 @@ class GprSource(Register, Single, OldSource):
|
|||||||
TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
|
TCGv {self.reg_tcg()} = hex_gpr[{self.reg_num}];
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_read(ctx, {self.reg_num});
|
ctx_log_reg_read(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -449,9 +476,8 @@ class GprNewSource(Register, Single, NewSource):
|
|||||||
TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
|
TCGv {self.reg_tcg()} = get_result_gpr(ctx, insn->regno[{regno}]);
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_read(ctx, {self.reg_num});
|
ctx_log_reg_read_new(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class GprReadWrite(Register, Single, ReadWrite):
|
class GprReadWrite(Register, Single, ReadWrite):
|
||||||
@ -471,8 +497,11 @@ class GprReadWrite(Register, Single, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
|
def analyze_read(self, f, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_reg_read(ctx, {self.reg_num});
|
||||||
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
||||||
@ -493,7 +522,6 @@ class ControlDest(Register, Single, Dest):
|
|||||||
gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_write_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
ctx_log_reg_write(ctx, {self.reg_num}, {predicated});
|
||||||
@ -511,7 +539,6 @@ class ControlSource(Register, Single, OldSource):
|
|||||||
gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_read_ctrl_reg(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_read(ctx, {self.reg_num});
|
ctx_log_reg_read(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -532,7 +559,6 @@ class ModifierSource(Register, Single, OldSource):
|
|||||||
declared.append(self.reg_tcg())
|
declared.append(self.reg_tcg())
|
||||||
declared.append("CS")
|
declared.append("CS")
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_read(ctx, {self.reg_num});
|
ctx_log_reg_read(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -548,7 +574,6 @@ class PredDest(Register, Single, Dest):
|
|||||||
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_pred_write(ctx, {self.reg_num});
|
ctx_log_pred_write(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -560,7 +585,6 @@ class PredSource(Register, Single, OldSource):
|
|||||||
TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
|
TCGv {self.reg_tcg()} = hex_pred[{self.reg_num}];
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_pred_read(ctx, {self.reg_num});
|
ctx_log_pred_read(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -571,9 +595,8 @@ class PredNewSource(Register, Single, NewSource):
|
|||||||
TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
|
TCGv {self.reg_tcg()} = get_result_pred(ctx, insn->regno[{regno}]);
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_pred_read(ctx, {self.reg_num});
|
ctx_log_pred_read_new(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class PredReadWrite(Register, Single, ReadWrite):
|
class PredReadWrite(Register, Single, ReadWrite):
|
||||||
@ -587,8 +610,11 @@ class PredReadWrite(Register, Single, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_log_pred_write(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
|
def analyze_read(self, f, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_pred_read(ctx, {self.reg_num});
|
||||||
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_pred_write(ctx, {self.reg_num});
|
ctx_log_pred_write(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -605,7 +631,6 @@ class PairDest(Register, Pair, Dest):
|
|||||||
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
||||||
@ -621,7 +646,6 @@ class PairSource(Register, Pair, OldSource):
|
|||||||
hex_gpr[{self.reg_num} + 1]);
|
hex_gpr[{self.reg_num} + 1]);
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -640,8 +664,11 @@ class PairReadWrite(Register, Pair, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_log_reg_write_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
|
def analyze_read(self, f, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
||||||
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
||||||
@ -663,7 +690,6 @@ class ControlPairDest(Register, Pair, Dest):
|
|||||||
gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_write_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
ctx_log_reg_write_pair(ctx, {self.reg_num}, {predicated});
|
||||||
@ -681,7 +707,6 @@ class ControlPairSource(Register, Pair, OldSource):
|
|||||||
gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
gen_read_ctrl_reg_pair(ctx, {self.reg_num}, {self.reg_tcg()});
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
ctx_log_reg_read_pair(ctx, {self.reg_num});
|
||||||
"""))
|
"""))
|
||||||
@ -705,11 +730,11 @@ class VRegDest(Register, Hvx, Dest):
|
|||||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
newv = hvx_newv(tag)
|
newv = hvx_newv(tag)
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
|
ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
|
||||||
|
insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegSource(Register, Hvx, OldSource):
|
class VRegSource(Register, Hvx, OldSource):
|
||||||
@ -728,9 +753,8 @@ class VRegSource(Register, Hvx, OldSource):
|
|||||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_read(ctx, {self.reg_num});
|
ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegNewSource(Register, Hvx, NewSource):
|
class VRegNewSource(Register, Hvx, NewSource):
|
||||||
@ -746,9 +770,8 @@ class VRegNewSource(Register, Hvx, NewSource):
|
|||||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_read(ctx, {self.reg_num});
|
ctx_log_vreg_read_new(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegReadWrite(Register, Hvx, ReadWrite):
|
class VRegReadWrite(Register, Hvx, ReadWrite):
|
||||||
@ -772,12 +795,16 @@ class VRegReadWrite(Register, Hvx, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
|
def analyze_read(self, f, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
newv = hvx_newv(tag)
|
newv = hvx_newv(tag)
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
|
ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
|
||||||
|
insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegTmp(Register, Hvx, ReadWrite):
|
class VRegTmp(Register, Hvx, ReadWrite):
|
||||||
@ -803,12 +830,16 @@ class VRegTmp(Register, Hvx, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVector *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
|
def analyze_read(self, f, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
newv = hvx_newv(tag)
|
newv = hvx_newv(tag)
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
|
ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
|
||||||
|
insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegPairDest(Register, Hvx, Dest):
|
class VRegPairDest(Register, Hvx, Dest):
|
||||||
@ -830,11 +861,11 @@ class VRegPairDest(Register, Hvx, Dest):
|
|||||||
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
newv = hvx_newv(tag)
|
newv = hvx_newv(tag)
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
|
ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated},
|
||||||
|
insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegPairSource(Register, Hvx, OldSource):
|
class VRegPairSource(Register, Hvx, OldSource):
|
||||||
@ -860,9 +891,8 @@ class VRegPairSource(Register, Hvx, OldSource):
|
|||||||
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_read_pair(ctx, {self.reg_num});
|
ctx_log_vreg_read_pair(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class VRegPairReadWrite(Register, Hvx, ReadWrite):
|
class VRegPairReadWrite(Register, Hvx, ReadWrite):
|
||||||
@ -892,12 +922,16 @@ class VRegPairReadWrite(Register, Hvx, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMVectorPair *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
|
def analyze_read(self, f, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_vreg_read_pair(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
newv = hvx_newv(tag)
|
newv = hvx_newv(tag)
|
||||||
predicated = "true" if is_predicated(tag) else "false"
|
predicated = "true" if is_predicated(tag) else "false"
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated});
|
ctx_log_vreg_write_pair(ctx, {self.reg_num}, {newv}, {predicated},
|
||||||
|
insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class QRegDest(Register, Hvx, Dest):
|
class QRegDest(Register, Hvx, Dest):
|
||||||
@ -919,9 +953,8 @@ class QRegDest(Register, Hvx, Dest):
|
|||||||
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_write(self, f, tag, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_qreg_write(ctx, {self.reg_num});
|
ctx_log_qreg_write(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class QRegSource(Register, Hvx, OldSource):
|
class QRegSource(Register, Hvx, OldSource):
|
||||||
@ -941,9 +974,8 @@ class QRegSource(Register, Hvx, OldSource):
|
|||||||
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_read(self, f, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_qreg_read(ctx, {self.reg_num});
|
ctx_log_qreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
class QRegReadWrite(Register, Hvx, ReadWrite):
|
class QRegReadWrite(Register, Hvx, ReadWrite):
|
||||||
@ -967,10 +999,13 @@ class QRegReadWrite(Register, Hvx, ReadWrite):
|
|||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
/* {self.reg_tcg()} is *(MMQReg *)({self.helper_arg_name()}) */
|
||||||
"""))
|
"""))
|
||||||
def analyze_write(self, f, tag, regno):
|
def analyze_read(self, f, regno):
|
||||||
self.decl_reg_num(f, regno)
|
|
||||||
f.write(code_fmt(f"""\
|
f.write(code_fmt(f"""\
|
||||||
ctx_log_qreg_write(ctx, {self.reg_num});
|
ctx_log_qreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
|
"""))
|
||||||
|
def analyze_write(self, f, tag, regno):
|
||||||
|
f.write(code_fmt(f"""\
|
||||||
|
ctx_log_qreg_write(ctx, {self.reg_num}, insn_has_hvx_helper);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
def init_registers():
|
def init_registers():
|
||||||
@ -1060,11 +1095,12 @@ def helper_args(tag, regs, imms):
|
|||||||
args = []
|
args = []
|
||||||
|
|
||||||
## First argument is the CPU state
|
## First argument is the CPU state
|
||||||
args.append(HelperArg(
|
if need_env(tag):
|
||||||
"env",
|
args.append(HelperArg(
|
||||||
"tcg_env",
|
"env",
|
||||||
"CPUHexagonState *env"
|
"tcg_env",
|
||||||
))
|
"CPUHexagonState *env"
|
||||||
|
))
|
||||||
|
|
||||||
## For predicated instructions, we pass in the destination register
|
## For predicated instructions, we pass in the destination register
|
||||||
if is_predicated(tag):
|
if is_predicated(tag):
|
||||||
@ -1118,6 +1154,18 @@ def helper_args(tag, regs, imms):
|
|||||||
"tcg_constant_tl(ctx->next_PC)",
|
"tcg_constant_tl(ctx->next_PC)",
|
||||||
"target_ulong next_PC"
|
"target_ulong next_PC"
|
||||||
))
|
))
|
||||||
|
if need_p0(tag):
|
||||||
|
args.append(HelperArg(
|
||||||
|
"i32",
|
||||||
|
"hex_pred[0]",
|
||||||
|
"uint32_t P0"
|
||||||
|
))
|
||||||
|
if need_sp(tag):
|
||||||
|
args.append(HelperArg(
|
||||||
|
"i32",
|
||||||
|
"hex_gpr[HEX_REG_SP]",
|
||||||
|
"uint32_t SP"
|
||||||
|
))
|
||||||
if need_slot(tag):
|
if need_slot(tag):
|
||||||
args.append(HelperArg(
|
args.append(HelperArg(
|
||||||
"i32",
|
"i32",
|
||||||
@ -1131,3 +1179,24 @@ def helper_args(tag, regs, imms):
|
|||||||
"uint32_t part1"
|
"uint32_t part1"
|
||||||
))
|
))
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
def read_common_files():
|
||||||
|
read_semantics_file(sys.argv[1])
|
||||||
|
read_overrides_file(sys.argv[2])
|
||||||
|
read_overrides_file(sys.argv[3])
|
||||||
|
## Whether or not idef-parser is enabled is
|
||||||
|
## determined by the number of arguments to
|
||||||
|
## this script:
|
||||||
|
##
|
||||||
|
## 4 args. -> not enabled,
|
||||||
|
## 5 args. -> idef-parser enabled.
|
||||||
|
##
|
||||||
|
## The 5:th arg. then holds a list of the successfully
|
||||||
|
## parsed instructions.
|
||||||
|
is_idef_parser_enabled = len(sys.argv) > 5
|
||||||
|
if is_idef_parser_enabled:
|
||||||
|
read_idef_parser_enabled_file(sys.argv[4])
|
||||||
|
calculate_attribs()
|
||||||
|
init_registers()
|
||||||
|
return is_idef_parser_enabled
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -39,6 +39,9 @@ struct Instruction {
|
|||||||
uint32_t slot:3;
|
uint32_t slot:3;
|
||||||
uint32_t which_extended:1; /* If has an extender, which immediate */
|
uint32_t which_extended:1; /* If has an extender, which immediate */
|
||||||
uint32_t new_value_producer_slot:4;
|
uint32_t new_value_producer_slot:4;
|
||||||
|
int32_t new_read_idx;
|
||||||
|
int32_t dest_idx;
|
||||||
|
bool has_pred_dest;
|
||||||
|
|
||||||
bool part1; /*
|
bool part1; /*
|
||||||
* cmp-jumps are split into two insns.
|
* cmp-jumps are split into two insns.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -343,7 +343,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
|
|||||||
|
|
||||||
#define fREAD_LR() (env->gpr[HEX_REG_LR])
|
#define fREAD_LR() (env->gpr[HEX_REG_LR])
|
||||||
|
|
||||||
#define fREAD_SP() (env->gpr[HEX_REG_SP])
|
#define fREAD_SP() (SP)
|
||||||
#define fREAD_LC0 (env->gpr[HEX_REG_LC0])
|
#define fREAD_LC0 (env->gpr[HEX_REG_LC0])
|
||||||
#define fREAD_LC1 (env->gpr[HEX_REG_LC1])
|
#define fREAD_LC1 (env->gpr[HEX_REG_LC1])
|
||||||
#define fREAD_SA0 (env->gpr[HEX_REG_SA0])
|
#define fREAD_SA0 (env->gpr[HEX_REG_SA0])
|
||||||
@ -358,7 +358,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
|
|||||||
#endif
|
#endif
|
||||||
#define fREAD_PC() (PC)
|
#define fREAD_PC() (PC)
|
||||||
|
|
||||||
#define fREAD_P0() (env->pred[0])
|
#define fREAD_P0() (P0)
|
||||||
|
|
||||||
#define fCHECK_PCALIGN(A)
|
#define fCHECK_PCALIGN(A)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
##
|
##
|
||||||
## Copyright(c) 2020-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
## Copyright(c) 2020-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
##
|
##
|
||||||
## This program is free software; you can redistribute it and/or modify
|
## This program is free software; you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
@ -18,7 +18,6 @@
|
|||||||
hexagon_ss = ss.source_set()
|
hexagon_ss = ss.source_set()
|
||||||
|
|
||||||
hex_common_py = 'hex_common.py'
|
hex_common_py = 'hex_common.py'
|
||||||
attribs_def = meson.current_source_dir() / 'attribs_def.h.inc'
|
|
||||||
gen_tcg_h = meson.current_source_dir() / 'gen_tcg.h'
|
gen_tcg_h = meson.current_source_dir() / 'gen_tcg.h'
|
||||||
gen_tcg_hvx_h = meson.current_source_dir() / 'gen_tcg_hvx.h'
|
gen_tcg_hvx_h = meson.current_source_dir() / 'gen_tcg_hvx.h'
|
||||||
idef_parser_dir = meson.current_source_dir() / 'idef-parser'
|
idef_parser_dir = meson.current_source_dir() / 'idef-parser'
|
||||||
@ -42,28 +41,17 @@ hexagon_ss.add(semantics_generated)
|
|||||||
#
|
#
|
||||||
# Step 2
|
# Step 2
|
||||||
# We use Python scripts to generate the following files
|
# We use Python scripts to generate the following files
|
||||||
# shortcode_generated.h.inc
|
|
||||||
# tcg_func_table_generated.c.inc
|
# tcg_func_table_generated.c.inc
|
||||||
# printinsn_generated.h.inc
|
# printinsn_generated.h.inc
|
||||||
# op_regs_generated.h.inc
|
|
||||||
# op_attribs_generated.h.inc
|
# op_attribs_generated.h.inc
|
||||||
# opcodes_def_generated.h.inc
|
# opcodes_def_generated.h.inc
|
||||||
#
|
#
|
||||||
shortcode_generated = custom_target(
|
|
||||||
'shortcode_generated.h.inc',
|
|
||||||
output: 'shortcode_generated.h.inc',
|
|
||||||
depends: [semantics_generated],
|
|
||||||
depend_files: [hex_common_py, attribs_def],
|
|
||||||
command: [python, files('gen_shortcode.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
|
||||||
)
|
|
||||||
hexagon_ss.add(shortcode_generated)
|
|
||||||
|
|
||||||
tcg_func_table_generated = custom_target(
|
tcg_func_table_generated = custom_target(
|
||||||
'tcg_func_table_generated.c.inc',
|
'tcg_func_table_generated.c.inc',
|
||||||
output: 'tcg_func_table_generated.c.inc',
|
output: 'tcg_func_table_generated.c.inc',
|
||||||
depends: [semantics_generated],
|
depends: [semantics_generated],
|
||||||
depend_files: [hex_common_py, attribs_def],
|
depend_files: [hex_common_py],
|
||||||
command: [python, files('gen_tcg_func_table.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
command: [python, files('gen_tcg_func_table.py'), semantics_generated, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(tcg_func_table_generated)
|
hexagon_ss.add(tcg_func_table_generated)
|
||||||
|
|
||||||
@ -71,26 +59,17 @@ printinsn_generated = custom_target(
|
|||||||
'printinsn_generated.h.inc',
|
'printinsn_generated.h.inc',
|
||||||
output: 'printinsn_generated.h.inc',
|
output: 'printinsn_generated.h.inc',
|
||||||
depends: [semantics_generated],
|
depends: [semantics_generated],
|
||||||
depend_files: [hex_common_py, attribs_def],
|
depend_files: [hex_common_py],
|
||||||
command: [python, files('gen_printinsn.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
command: [python, files('gen_printinsn.py'), semantics_generated, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(printinsn_generated)
|
hexagon_ss.add(printinsn_generated)
|
||||||
|
|
||||||
op_regs_generated = custom_target(
|
|
||||||
'op_regs_generated.h.inc',
|
|
||||||
output: 'op_regs_generated.h.inc',
|
|
||||||
depends: [semantics_generated],
|
|
||||||
depend_files: [hex_common_py, attribs_def],
|
|
||||||
command: [python, files('gen_op_regs.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
|
||||||
)
|
|
||||||
hexagon_ss.add(op_regs_generated)
|
|
||||||
|
|
||||||
op_attribs_generated = custom_target(
|
op_attribs_generated = custom_target(
|
||||||
'op_attribs_generated.h.inc',
|
'op_attribs_generated.h.inc',
|
||||||
output: 'op_attribs_generated.h.inc',
|
output: 'op_attribs_generated.h.inc',
|
||||||
depends: [semantics_generated],
|
depends: [semantics_generated],
|
||||||
depend_files: [hex_common_py, attribs_def],
|
depend_files: [hex_common_py],
|
||||||
command: [python, files('gen_op_attribs.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
command: [python, files('gen_op_attribs.py'), semantics_generated, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(op_attribs_generated)
|
hexagon_ss.add(op_attribs_generated)
|
||||||
|
|
||||||
@ -98,8 +77,8 @@ opcodes_def_generated = custom_target(
|
|||||||
'opcodes_def_generated.h.inc',
|
'opcodes_def_generated.h.inc',
|
||||||
output: 'opcodes_def_generated.h.inc',
|
output: 'opcodes_def_generated.h.inc',
|
||||||
depends: [semantics_generated],
|
depends: [semantics_generated],
|
||||||
depend_files: [hex_common_py, attribs_def],
|
depend_files: [hex_common_py],
|
||||||
command: [python, files('gen_opcodes_def.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
command: [python, files('gen_opcodes_def.py'), semantics_generated, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(opcodes_def_generated)
|
hexagon_ss.add(opcodes_def_generated)
|
||||||
|
|
||||||
@ -110,7 +89,7 @@ hexagon_ss.add(opcodes_def_generated)
|
|||||||
#
|
#
|
||||||
gen_dectree_import = executable(
|
gen_dectree_import = executable(
|
||||||
'gen_dectree_import',
|
'gen_dectree_import',
|
||||||
'gen_dectree_import.c', opcodes_def_generated, op_regs_generated,
|
'gen_dectree_import.c', opcodes_def_generated,
|
||||||
native: true, build_by_default: false)
|
native: true, build_by_default: false)
|
||||||
|
|
||||||
iset_py = custom_target(
|
iset_py = custom_target(
|
||||||
@ -298,7 +277,7 @@ if idef_parser_enabled and 'hexagon-linux-user' in target_dirs
|
|||||||
output: 'idef_parser_input.h.inc',
|
output: 'idef_parser_input.h.inc',
|
||||||
depends: [semantics_generated],
|
depends: [semantics_generated],
|
||||||
depend_files: [hex_common_py],
|
depend_files: [hex_common_py],
|
||||||
command: [python, files('gen_idef_parser_funcs.py'), semantics_generated, attribs_def, '@OUTPUT@'],
|
command: [python, files('gen_idef_parser_funcs.py'), semantics_generated, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
|
|
||||||
preprocessed_idef_parser_input_generated = custom_target(
|
preprocessed_idef_parser_input_generated = custom_target(
|
||||||
@ -367,12 +346,12 @@ if idef_parser_enabled and 'hexagon-linux-user' in target_dirs
|
|||||||
# Setup input and dependencies for the next step, this depends on whether or
|
# Setup input and dependencies for the next step, this depends on whether or
|
||||||
# not idef-parser is enabled
|
# not idef-parser is enabled
|
||||||
helper_dep = [semantics_generated, idef_generated_tcg_c, idef_generated_tcg]
|
helper_dep = [semantics_generated, idef_generated_tcg_c, idef_generated_tcg]
|
||||||
helper_in = [semantics_generated, attribs_def, gen_tcg_h, gen_tcg_hvx_h, idef_generated_list]
|
helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h, idef_generated_list]
|
||||||
else
|
else
|
||||||
# Setup input and dependencies for the next step, this depends on whether or
|
# Setup input and dependencies for the next step, this depends on whether or
|
||||||
# not idef-parser is enabled
|
# not idef-parser is enabled
|
||||||
helper_dep = [semantics_generated]
|
helper_dep = [semantics_generated]
|
||||||
helper_in = [semantics_generated, attribs_def, gen_tcg_h, gen_tcg_hvx_h]
|
helper_in = [semantics_generated, gen_tcg_h, gen_tcg_hvx_h]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -386,7 +365,7 @@ helper_protos_generated = custom_target(
|
|||||||
'helper_protos_generated.h.inc',
|
'helper_protos_generated.h.inc',
|
||||||
output: 'helper_protos_generated.h.inc',
|
output: 'helper_protos_generated.h.inc',
|
||||||
depends: helper_dep,
|
depends: helper_dep,
|
||||||
depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
|
depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
|
||||||
command: [python, files('gen_helper_protos.py'), helper_in, '@OUTPUT@'],
|
command: [python, files('gen_helper_protos.py'), helper_in, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(helper_protos_generated)
|
hexagon_ss.add(helper_protos_generated)
|
||||||
@ -395,7 +374,7 @@ helper_funcs_generated = custom_target(
|
|||||||
'helper_funcs_generated.c.inc',
|
'helper_funcs_generated.c.inc',
|
||||||
output: 'helper_funcs_generated.c.inc',
|
output: 'helper_funcs_generated.c.inc',
|
||||||
depends: helper_dep,
|
depends: helper_dep,
|
||||||
depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
|
depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
|
||||||
command: [python, files('gen_helper_funcs.py'), helper_in, '@OUTPUT@'],
|
command: [python, files('gen_helper_funcs.py'), helper_in, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(helper_funcs_generated)
|
hexagon_ss.add(helper_funcs_generated)
|
||||||
@ -404,7 +383,7 @@ tcg_funcs_generated = custom_target(
|
|||||||
'tcg_funcs_generated.c.inc',
|
'tcg_funcs_generated.c.inc',
|
||||||
output: 'tcg_funcs_generated.c.inc',
|
output: 'tcg_funcs_generated.c.inc',
|
||||||
depends: helper_dep,
|
depends: helper_dep,
|
||||||
depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
|
depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
|
||||||
command: [python, files('gen_tcg_funcs.py'), helper_in, '@OUTPUT@'],
|
command: [python, files('gen_tcg_funcs.py'), helper_in, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(tcg_funcs_generated)
|
hexagon_ss.add(tcg_funcs_generated)
|
||||||
@ -413,7 +392,7 @@ analyze_funcs_generated = custom_target(
|
|||||||
'analyze_funcs_generated.c.inc',
|
'analyze_funcs_generated.c.inc',
|
||||||
output: 'analyze_funcs_generated.c.inc',
|
output: 'analyze_funcs_generated.c.inc',
|
||||||
depends: helper_dep,
|
depends: helper_dep,
|
||||||
depend_files: [hex_common_py, attribs_def, gen_tcg_h, gen_tcg_hvx_h],
|
depend_files: [hex_common_py, gen_tcg_h, gen_tcg_hvx_h],
|
||||||
command: [python, files('gen_analyze_funcs.py'), helper_in, '@OUTPUT@'],
|
command: [python, files('gen_analyze_funcs.py'), helper_in, '@OUTPUT@'],
|
||||||
)
|
)
|
||||||
hexagon_ss.add(analyze_funcs_generated)
|
hexagon_ss.add(analyze_funcs_generated)
|
||||||
|
@ -28,19 +28,15 @@ check_new_value(Packet *pkt)
|
|||||||
{
|
{
|
||||||
/* .new value for a MMVector store */
|
/* .new value for a MMVector store */
|
||||||
int i, j;
|
int i, j;
|
||||||
const char *reginfo;
|
|
||||||
const char *destletters;
|
|
||||||
const char *dststr = NULL;
|
|
||||||
uint16_t def_opcode;
|
uint16_t def_opcode;
|
||||||
char letter;
|
|
||||||
|
|
||||||
for (i = 1; i < pkt->num_insns; i++) {
|
for (i = 1; i < pkt->num_insns; i++) {
|
||||||
uint16_t use_opcode = pkt->insn[i].opcode;
|
uint16_t use_opcode = pkt->insn[i].opcode;
|
||||||
if (GET_ATTRIB(use_opcode, A_DOTNEWVALUE) &&
|
if (GET_ATTRIB(use_opcode, A_DOTNEWVALUE) &&
|
||||||
GET_ATTRIB(use_opcode, A_CVI) &&
|
GET_ATTRIB(use_opcode, A_CVI) &&
|
||||||
GET_ATTRIB(use_opcode, A_STORE)) {
|
GET_ATTRIB(use_opcode, A_STORE)) {
|
||||||
int use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
|
int use_regidx = pkt->insn[i].new_read_idx;
|
||||||
opcode_reginfo[use_opcode];
|
g_assert(pkt->insn[i].new_read_idx != -1);
|
||||||
/*
|
/*
|
||||||
* What's encoded at the N-field is the offset to who's producing
|
* What's encoded at the N-field is the offset to who's producing
|
||||||
* the value.
|
* the value.
|
||||||
@ -68,31 +64,19 @@ check_new_value(Packet *pkt)
|
|||||||
|
|
||||||
/* def_idx is the index of the producer */
|
/* def_idx is the index of the producer */
|
||||||
def_opcode = pkt->insn[def_idx].opcode;
|
def_opcode = pkt->insn[def_idx].opcode;
|
||||||
reginfo = opcode_reginfo[def_opcode];
|
if ((pkt->insn[def_idx].dest_idx == -1) &&
|
||||||
destletters = "dexy";
|
GET_ATTRIB(def_opcode, A_CVI_GATHER)) {
|
||||||
for (j = 0; (letter = destletters[j]) != 0; j++) {
|
|
||||||
dststr = strchr(reginfo, letter);
|
|
||||||
if (dststr != NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((dststr == NULL) && GET_ATTRIB(def_opcode, A_CVI_GATHER)) {
|
|
||||||
pkt->insn[i].regno[use_regidx] = def_oreg;
|
pkt->insn[i].regno[use_regidx] = def_oreg;
|
||||||
pkt->insn[i].new_value_producer_slot = pkt->insn[def_idx].slot;
|
pkt->insn[i].new_value_producer_slot = pkt->insn[def_idx].slot;
|
||||||
} else {
|
} else {
|
||||||
if (dststr == NULL) {
|
if (pkt->insn[def_idx].dest_idx == -1) {
|
||||||
/* still not there, we have a bad packet */
|
/* still not there, we have a bad packet */
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
int def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
|
int def_regnum =
|
||||||
|
pkt->insn[def_idx].regno[pkt->insn[def_idx].dest_idx];
|
||||||
/* Now patch up the consumer with the register number */
|
/* Now patch up the consumer with the register number */
|
||||||
pkt->insn[i].regno[use_regidx] = def_regnum ^ def_oreg;
|
pkt->insn[i].regno[use_regidx] = def_regnum ^ def_oreg;
|
||||||
/* special case for (Vx,Vy) */
|
|
||||||
dststr = strchr(reginfo, 'y');
|
|
||||||
if (def_oreg && strchr(reginfo, 'x') && dststr) {
|
|
||||||
def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
|
|
||||||
pkt->insn[i].regno[use_regidx] = def_regnum;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* We need to remember who produces this value to later
|
* We need to remember who produces this value to later
|
||||||
* check if it was dynamically cancelled
|
* check if it was dynamically cancelled
|
||||||
|
@ -36,41 +36,6 @@ const char * const opcode_names[] = {
|
|||||||
#undef OPCODE
|
#undef OPCODE
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * const opcode_reginfo[] = {
|
|
||||||
#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */
|
|
||||||
#define REGINFO(TAG, REGINFO, RREGS, WREGS) REGINFO,
|
|
||||||
#include "op_regs_generated.h.inc"
|
|
||||||
NULL
|
|
||||||
#undef REGINFO
|
|
||||||
#undef IMMINFO
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const char * const opcode_rregs[] = {
|
|
||||||
#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */
|
|
||||||
#define REGINFO(TAG, REGINFO, RREGS, WREGS) RREGS,
|
|
||||||
#include "op_regs_generated.h.inc"
|
|
||||||
NULL
|
|
||||||
#undef REGINFO
|
|
||||||
#undef IMMINFO
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const char * const opcode_wregs[] = {
|
|
||||||
#define IMMINFO(TAG, SIGN, SIZE, SHAMT, SIGN2, SIZE2, SHAMT2) /* nothing */
|
|
||||||
#define REGINFO(TAG, REGINFO, RREGS, WREGS) WREGS,
|
|
||||||
#include "op_regs_generated.h.inc"
|
|
||||||
NULL
|
|
||||||
#undef REGINFO
|
|
||||||
#undef IMMINFO
|
|
||||||
};
|
|
||||||
|
|
||||||
const char * const opcode_short_semantics[] = {
|
|
||||||
#define DEF_SHORTCODE(TAG, SHORTCODE) [TAG] = #SHORTCODE,
|
|
||||||
#include "shortcode_generated.h.inc"
|
|
||||||
#undef DEF_SHORTCODE
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB);
|
DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB);
|
||||||
|
|
||||||
|
@ -40,10 +40,6 @@ typedef enum {
|
|||||||
|
|
||||||
extern const char * const opcode_names[];
|
extern const char * const opcode_names[];
|
||||||
|
|
||||||
extern const char * const opcode_reginfo[];
|
|
||||||
extern const char * const opcode_rregs[];
|
|
||||||
extern const char * const opcode_wregs[];
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char * const encoding;
|
const char * const encoding;
|
||||||
const EncClass enc_class;
|
const EncClass enc_class;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -380,70 +380,8 @@ static bool need_commit(DisasContext *ctx)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkt->num_insns == 1) {
|
if (ctx->read_after_write || ctx->has_hvx_overlap) {
|
||||||
if (pkt->pkt_has_hvx) {
|
return true;
|
||||||
/*
|
|
||||||
* The HVX instructions with generated helpers use
|
|
||||||
* pass-by-reference, so they need the read/write overlap
|
|
||||||
* check below.
|
|
||||||
* The HVX instructions with overrides are OK.
|
|
||||||
*/
|
|
||||||
if (!ctx->has_hvx_helper) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for overlap between register reads and writes */
|
|
||||||
for (int i = 0; i < ctx->reg_log_idx; i++) {
|
|
||||||
int rnum = ctx->reg_log[i];
|
|
||||||
if (test_bit(rnum, ctx->regs_read)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for overlap between predicate reads and writes */
|
|
||||||
for (int i = 0; i < ctx->preg_log_idx; i++) {
|
|
||||||
int pnum = ctx->preg_log[i];
|
|
||||||
if (test_bit(pnum, ctx->pregs_read)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for overlap between HVX reads and writes */
|
|
||||||
for (int i = 0; i < ctx->vreg_log_idx; i++) {
|
|
||||||
int vnum = ctx->vreg_log[i];
|
|
||||||
if (test_bit(vnum, ctx->vregs_read)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!bitmap_empty(ctx->vregs_updated_tmp, NUM_VREGS)) {
|
|
||||||
int i = find_first_bit(ctx->vregs_updated_tmp, NUM_VREGS);
|
|
||||||
while (i < NUM_VREGS) {
|
|
||||||
if (test_bit(i, ctx->vregs_read)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
i = find_next_bit(ctx->vregs_updated_tmp, NUM_VREGS, i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!bitmap_empty(ctx->vregs_select, NUM_VREGS)) {
|
|
||||||
int i = find_first_bit(ctx->vregs_select, NUM_VREGS);
|
|
||||||
while (i < NUM_VREGS) {
|
|
||||||
if (test_bit(i, ctx->vregs_read)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
i = find_next_bit(ctx->vregs_select, NUM_VREGS, i + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for overlap between HVX predicate reads and writes */
|
|
||||||
for (int i = 0; i < ctx->qreg_log_idx; i++) {
|
|
||||||
int qnum = ctx->qreg_log[i];
|
|
||||||
if (test_bit(qnum, ctx->qregs_read)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -467,7 +405,8 @@ static void mark_implicit_pred_reads(DisasContext *ctx)
|
|||||||
static void analyze_packet(DisasContext *ctx)
|
static void analyze_packet(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
Packet *pkt = ctx->pkt;
|
Packet *pkt = ctx->pkt;
|
||||||
ctx->has_hvx_helper = false;
|
ctx->read_after_write = false;
|
||||||
|
ctx->has_hvx_overlap = false;
|
||||||
for (int i = 0; i < pkt->num_insns; i++) {
|
for (int i = 0; i < pkt->num_insns; i++) {
|
||||||
Insn *insn = &pkt->insn[i];
|
Insn *insn = &pkt->insn[i];
|
||||||
ctx->insn = insn;
|
ctx->insn = insn;
|
||||||
@ -492,21 +431,19 @@ static void gen_start_packet(DisasContext *ctx)
|
|||||||
ctx->next_PC = next_PC;
|
ctx->next_PC = next_PC;
|
||||||
ctx->reg_log_idx = 0;
|
ctx->reg_log_idx = 0;
|
||||||
bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
|
bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
|
||||||
bitmap_zero(ctx->regs_read, TOTAL_PER_THREAD_REGS);
|
|
||||||
bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
|
bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
|
||||||
ctx->preg_log_idx = 0;
|
ctx->preg_log_idx = 0;
|
||||||
bitmap_zero(ctx->pregs_written, NUM_PREGS);
|
bitmap_zero(ctx->pregs_written, NUM_PREGS);
|
||||||
bitmap_zero(ctx->pregs_read, NUM_PREGS);
|
|
||||||
ctx->future_vregs_idx = 0;
|
ctx->future_vregs_idx = 0;
|
||||||
ctx->tmp_vregs_idx = 0;
|
ctx->tmp_vregs_idx = 0;
|
||||||
ctx->vreg_log_idx = 0;
|
ctx->vreg_log_idx = 0;
|
||||||
|
bitmap_zero(ctx->vregs_written, NUM_VREGS);
|
||||||
bitmap_zero(ctx->vregs_updated_tmp, NUM_VREGS);
|
bitmap_zero(ctx->vregs_updated_tmp, NUM_VREGS);
|
||||||
bitmap_zero(ctx->vregs_updated, NUM_VREGS);
|
bitmap_zero(ctx->vregs_updated, NUM_VREGS);
|
||||||
bitmap_zero(ctx->vregs_select, NUM_VREGS);
|
bitmap_zero(ctx->vregs_select, NUM_VREGS);
|
||||||
bitmap_zero(ctx->predicated_future_vregs, NUM_VREGS);
|
bitmap_zero(ctx->predicated_future_vregs, NUM_VREGS);
|
||||||
bitmap_zero(ctx->predicated_tmp_vregs, NUM_VREGS);
|
bitmap_zero(ctx->predicated_tmp_vregs, NUM_VREGS);
|
||||||
bitmap_zero(ctx->vregs_read, NUM_VREGS);
|
bitmap_zero(ctx->qregs_written, NUM_QREGS);
|
||||||
bitmap_zero(ctx->qregs_read, NUM_QREGS);
|
|
||||||
ctx->qreg_log_idx = 0;
|
ctx->qreg_log_idx = 0;
|
||||||
for (i = 0; i < STORES_MAX; i++) {
|
for (i = 0; i < STORES_MAX; i++) {
|
||||||
ctx->store_width[i] = 0;
|
ctx->store_width[i] = 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -38,12 +38,10 @@ typedef struct DisasContext {
|
|||||||
int reg_log[REG_WRITES_MAX];
|
int reg_log[REG_WRITES_MAX];
|
||||||
int reg_log_idx;
|
int reg_log_idx;
|
||||||
DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
|
DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
|
||||||
DECLARE_BITMAP(regs_read, TOTAL_PER_THREAD_REGS);
|
|
||||||
DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
|
DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
|
||||||
int preg_log[PRED_WRITES_MAX];
|
int preg_log[PRED_WRITES_MAX];
|
||||||
int preg_log_idx;
|
int preg_log_idx;
|
||||||
DECLARE_BITMAP(pregs_written, NUM_PREGS);
|
DECLARE_BITMAP(pregs_written, NUM_PREGS);
|
||||||
DECLARE_BITMAP(pregs_read, NUM_PREGS);
|
|
||||||
uint8_t store_width[STORES_MAX];
|
uint8_t store_width[STORES_MAX];
|
||||||
bool s1_store_processed;
|
bool s1_store_processed;
|
||||||
int future_vregs_idx;
|
int future_vregs_idx;
|
||||||
@ -52,22 +50,27 @@ typedef struct DisasContext {
|
|||||||
int tmp_vregs_num[VECTOR_TEMPS_MAX];
|
int tmp_vregs_num[VECTOR_TEMPS_MAX];
|
||||||
int vreg_log[NUM_VREGS];
|
int vreg_log[NUM_VREGS];
|
||||||
int vreg_log_idx;
|
int vreg_log_idx;
|
||||||
|
DECLARE_BITMAP(vregs_written, NUM_VREGS);
|
||||||
|
DECLARE_BITMAP(insn_vregs_written, NUM_VREGS);
|
||||||
DECLARE_BITMAP(vregs_updated_tmp, NUM_VREGS);
|
DECLARE_BITMAP(vregs_updated_tmp, NUM_VREGS);
|
||||||
DECLARE_BITMAP(vregs_updated, NUM_VREGS);
|
DECLARE_BITMAP(vregs_updated, NUM_VREGS);
|
||||||
DECLARE_BITMAP(vregs_select, NUM_VREGS);
|
DECLARE_BITMAP(vregs_select, NUM_VREGS);
|
||||||
DECLARE_BITMAP(predicated_future_vregs, NUM_VREGS);
|
DECLARE_BITMAP(predicated_future_vregs, NUM_VREGS);
|
||||||
DECLARE_BITMAP(predicated_tmp_vregs, NUM_VREGS);
|
DECLARE_BITMAP(predicated_tmp_vregs, NUM_VREGS);
|
||||||
DECLARE_BITMAP(vregs_read, NUM_VREGS);
|
DECLARE_BITMAP(insn_vregs_read, NUM_VREGS);
|
||||||
int qreg_log[NUM_QREGS];
|
int qreg_log[NUM_QREGS];
|
||||||
int qreg_log_idx;
|
int qreg_log_idx;
|
||||||
DECLARE_BITMAP(qregs_read, NUM_QREGS);
|
DECLARE_BITMAP(qregs_written, NUM_QREGS);
|
||||||
|
DECLARE_BITMAP(insn_qregs_written, NUM_QREGS);
|
||||||
|
DECLARE_BITMAP(insn_qregs_read, NUM_QREGS);
|
||||||
bool pre_commit;
|
bool pre_commit;
|
||||||
bool need_commit;
|
bool need_commit;
|
||||||
TCGCond branch_cond;
|
TCGCond branch_cond;
|
||||||
target_ulong branch_dest;
|
target_ulong branch_dest;
|
||||||
bool is_tight_loop;
|
bool is_tight_loop;
|
||||||
bool short_circuit;
|
bool short_circuit;
|
||||||
bool has_hvx_helper;
|
bool read_after_write;
|
||||||
|
bool has_hvx_overlap;
|
||||||
TCGv new_value[TOTAL_PER_THREAD_REGS];
|
TCGv new_value[TOTAL_PER_THREAD_REGS];
|
||||||
TCGv new_pred_value[NUM_PREGS];
|
TCGv new_pred_value[NUM_PREGS];
|
||||||
TCGv pred_written;
|
TCGv pred_written;
|
||||||
@ -75,6 +78,8 @@ typedef struct DisasContext {
|
|||||||
TCGv dczero_addr;
|
TCGv dczero_addr;
|
||||||
} DisasContext;
|
} DisasContext;
|
||||||
|
|
||||||
|
bool is_gather_store_insn(DisasContext *ctx);
|
||||||
|
|
||||||
static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
|
static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
|
||||||
{
|
{
|
||||||
if (!test_bit(pnum, ctx->pregs_written)) {
|
if (!test_bit(pnum, ctx->pregs_written)) {
|
||||||
@ -86,7 +91,14 @@ static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
|
|||||||
|
|
||||||
static inline void ctx_log_pred_read(DisasContext *ctx, int pnum)
|
static inline void ctx_log_pred_read(DisasContext *ctx, int pnum)
|
||||||
{
|
{
|
||||||
set_bit(pnum, ctx->pregs_read);
|
if (test_bit(pnum, ctx->pregs_written)) {
|
||||||
|
ctx->read_after_write = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ctx_log_pred_read_new(DisasContext *ctx, int pnum)
|
||||||
|
{
|
||||||
|
g_assert(test_bit(pnum, ctx->pregs_written));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ctx_log_reg_write(DisasContext *ctx, int rnum,
|
static inline void ctx_log_reg_write(DisasContext *ctx, int rnum,
|
||||||
@ -117,7 +129,14 @@ static inline void ctx_log_reg_write_pair(DisasContext *ctx, int rnum,
|
|||||||
|
|
||||||
static inline void ctx_log_reg_read(DisasContext *ctx, int rnum)
|
static inline void ctx_log_reg_read(DisasContext *ctx, int rnum)
|
||||||
{
|
{
|
||||||
set_bit(rnum, ctx->regs_read);
|
if (test_bit(rnum, ctx->regs_written)) {
|
||||||
|
ctx->read_after_write = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ctx_log_reg_read_new(DisasContext *ctx, int rnum)
|
||||||
|
{
|
||||||
|
g_assert(test_bit(rnum, ctx->regs_written));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ctx_log_reg_read_pair(DisasContext *ctx, int rnum)
|
static inline void ctx_log_reg_read_pair(DisasContext *ctx, int rnum)
|
||||||
@ -131,10 +150,25 @@ intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
|
|||||||
intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
|
intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
|
||||||
int num, bool alloc_ok);
|
int num, bool alloc_ok);
|
||||||
|
|
||||||
|
static inline void ctx_start_hvx_insn(DisasContext *ctx)
|
||||||
|
{
|
||||||
|
bitmap_zero(ctx->insn_vregs_written, NUM_VREGS);
|
||||||
|
bitmap_zero(ctx->insn_vregs_read, NUM_VREGS);
|
||||||
|
bitmap_zero(ctx->insn_qregs_written, NUM_QREGS);
|
||||||
|
bitmap_zero(ctx->insn_qregs_read, NUM_QREGS);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void ctx_log_vreg_write(DisasContext *ctx,
|
static inline void ctx_log_vreg_write(DisasContext *ctx,
|
||||||
int rnum, VRegWriteType type,
|
int rnum, VRegWriteType type,
|
||||||
bool is_predicated)
|
bool is_predicated, bool has_helper)
|
||||||
{
|
{
|
||||||
|
if (has_helper) {
|
||||||
|
set_bit(rnum, ctx->insn_vregs_written);
|
||||||
|
if (test_bit(rnum, ctx->insn_vregs_read)) {
|
||||||
|
ctx->has_hvx_overlap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bit(rnum, ctx->vregs_written);
|
||||||
if (type != EXT_TMP) {
|
if (type != EXT_TMP) {
|
||||||
if (!test_bit(rnum, ctx->vregs_updated)) {
|
if (!test_bit(rnum, ctx->vregs_updated)) {
|
||||||
ctx->vreg_log[ctx->vreg_log_idx] = rnum;
|
ctx->vreg_log[ctx->vreg_log_idx] = rnum;
|
||||||
@ -160,33 +194,77 @@ static inline void ctx_log_vreg_write(DisasContext *ctx,
|
|||||||
|
|
||||||
static inline void ctx_log_vreg_write_pair(DisasContext *ctx,
|
static inline void ctx_log_vreg_write_pair(DisasContext *ctx,
|
||||||
int rnum, VRegWriteType type,
|
int rnum, VRegWriteType type,
|
||||||
bool is_predicated)
|
bool is_predicated, bool has_helper)
|
||||||
{
|
{
|
||||||
ctx_log_vreg_write(ctx, rnum ^ 0, type, is_predicated);
|
ctx_log_vreg_write(ctx, rnum ^ 0, type, is_predicated, has_helper);
|
||||||
ctx_log_vreg_write(ctx, rnum ^ 1, type, is_predicated);
|
ctx_log_vreg_write(ctx, rnum ^ 1, type, is_predicated, has_helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ctx_log_vreg_read(DisasContext *ctx, int rnum)
|
static inline void ctx_log_vreg_read(DisasContext *ctx, int rnum,
|
||||||
|
bool has_helper)
|
||||||
{
|
{
|
||||||
set_bit(rnum, ctx->vregs_read);
|
if (has_helper) {
|
||||||
|
set_bit(rnum, ctx->insn_vregs_read);
|
||||||
|
if (test_bit(rnum, ctx->insn_vregs_written)) {
|
||||||
|
ctx->has_hvx_overlap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (test_bit(rnum, ctx->vregs_written)) {
|
||||||
|
ctx->read_after_write = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ctx_log_vreg_read_pair(DisasContext *ctx, int rnum)
|
static inline void ctx_log_vreg_read_new(DisasContext *ctx, int rnum,
|
||||||
|
bool has_helper)
|
||||||
{
|
{
|
||||||
ctx_log_vreg_read(ctx, rnum ^ 0);
|
g_assert(is_gather_store_insn(ctx) ||
|
||||||
ctx_log_vreg_read(ctx, rnum ^ 1);
|
test_bit(rnum, ctx->vregs_updated) ||
|
||||||
|
test_bit(rnum, ctx->vregs_select) ||
|
||||||
|
test_bit(rnum, ctx->vregs_updated_tmp));
|
||||||
|
if (has_helper) {
|
||||||
|
set_bit(rnum, ctx->insn_vregs_read);
|
||||||
|
if (test_bit(rnum, ctx->insn_vregs_written)) {
|
||||||
|
ctx->has_hvx_overlap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_gather_store_insn(ctx)) {
|
||||||
|
ctx->read_after_write = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ctx_log_vreg_read_pair(DisasContext *ctx, int rnum,
|
||||||
|
bool has_helper)
|
||||||
|
{
|
||||||
|
ctx_log_vreg_read(ctx, rnum ^ 0, has_helper);
|
||||||
|
ctx_log_vreg_read(ctx, rnum ^ 1, has_helper);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ctx_log_qreg_write(DisasContext *ctx,
|
static inline void ctx_log_qreg_write(DisasContext *ctx,
|
||||||
int rnum)
|
int rnum, bool has_helper)
|
||||||
{
|
{
|
||||||
|
if (has_helper) {
|
||||||
|
set_bit(rnum, ctx->insn_qregs_written);
|
||||||
|
if (test_bit(rnum, ctx->insn_qregs_read)) {
|
||||||
|
ctx->has_hvx_overlap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_bit(rnum, ctx->qregs_written);
|
||||||
ctx->qreg_log[ctx->qreg_log_idx] = rnum;
|
ctx->qreg_log[ctx->qreg_log_idx] = rnum;
|
||||||
ctx->qreg_log_idx++;
|
ctx->qreg_log_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ctx_log_qreg_read(DisasContext *ctx, int qnum)
|
static inline void ctx_log_qreg_read(DisasContext *ctx,
|
||||||
|
int qnum, bool has_helper)
|
||||||
{
|
{
|
||||||
set_bit(qnum, ctx->qregs_read);
|
if (has_helper) {
|
||||||
|
set_bit(qnum, ctx->insn_qregs_read);
|
||||||
|
if (test_bit(qnum, ctx->insn_qregs_written)) {
|
||||||
|
ctx->has_hvx_overlap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (test_bit(qnum, ctx->qregs_written)) {
|
||||||
|
ctx->read_after_write = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
|
extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
|
||||||
@ -205,7 +283,6 @@ extern TCGv hex_vstore_addr[VSTORES_MAX];
|
|||||||
extern TCGv hex_vstore_size[VSTORES_MAX];
|
extern TCGv hex_vstore_size[VSTORES_MAX];
|
||||||
extern TCGv hex_vstore_pending[VSTORES_MAX];
|
extern TCGv hex_vstore_pending[VSTORES_MAX];
|
||||||
|
|
||||||
bool is_gather_store_insn(DisasContext *ctx);
|
|
||||||
void process_store(DisasContext *ctx, int slot_num);
|
void process_store(DisasContext *ctx, int slot_num);
|
||||||
|
|
||||||
FIELD(PROBE_PKT_SCALAR_STORE_S0, MMU_IDX, 0, 2)
|
FIELD(PROBE_PKT_SCALAR_STORE_S0, MMU_IDX, 0, 2)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright(c) 2021-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2021-2024 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -231,6 +231,7 @@ static void test_masked_store(bool invert)
|
|||||||
static void test_new_value_store(void)
|
static void test_new_value_store(void)
|
||||||
{
|
{
|
||||||
void *p0 = buffer0;
|
void *p0 = buffer0;
|
||||||
|
void *p1 = buffer1;
|
||||||
void *pout = output;
|
void *pout = output;
|
||||||
|
|
||||||
asm("{\n\t"
|
asm("{\n\t"
|
||||||
@ -242,6 +243,19 @@ static void test_new_value_store(void)
|
|||||||
expect[0] = buffer0[0];
|
expect[0] = buffer0[0];
|
||||||
|
|
||||||
check_output_w(__LINE__, 1);
|
check_output_w(__LINE__, 1);
|
||||||
|
|
||||||
|
/* Test the .new read from the high half of a pair */
|
||||||
|
asm("v7 = vmem(%0 + #0)\n\t"
|
||||||
|
"v12 = vmem(%1 + #0)\n\t"
|
||||||
|
"{\n\t"
|
||||||
|
" v5:4 = vcombine(v12, v7)\n\t"
|
||||||
|
" vmem(%2 + #0) = v5.new\n\t"
|
||||||
|
"}\n\t"
|
||||||
|
: : "r"(p0), "r"(p1), "r"(pout) : "v4", "v5", "v7", "v12", "memory");
|
||||||
|
|
||||||
|
expect[0] = buffer1[0];
|
||||||
|
|
||||||
|
check_output_w(__LINE__, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_max_temps()
|
static void test_max_temps()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user