Hexagon (target/hexagon) Move pkt_has_store_s1 to DisasContext
The pkt_has_store_s1 field is only used for bookkeeping helpers with a load. With recent changes that eliminate the need to free TCGv variables, it makes more sense to make this transient. These helpers already take the instruction slot as an argument. We combine the slot and pkt_has_store_s1 into a single argument called slotval. Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230427230012.3800327-21-tsimpson@quicinc.com>
This commit is contained in:
parent
842b206f26
commit
e5d0d78db4
@ -99,7 +99,6 @@ typedef struct CPUArchState {
|
|||||||
target_ulong reg_written[TOTAL_PER_THREAD_REGS];
|
target_ulong reg_written[TOTAL_PER_THREAD_REGS];
|
||||||
|
|
||||||
MemLog mem_log_stores[STORES_MAX];
|
MemLog mem_log_stores[STORES_MAX];
|
||||||
target_ulong pkt_has_store_s1;
|
|
||||||
target_ulong dczero_addr;
|
target_ulong dczero_addr;
|
||||||
|
|
||||||
float_status fp_status;
|
float_status fp_status;
|
||||||
|
@ -209,8 +209,6 @@ def gen_analyze_func(f, tag, regs, imms):
|
|||||||
has_generated_helper = not hex_common.skip_qemu_helper(
|
has_generated_helper = not hex_common.skip_qemu_helper(
|
||||||
tag
|
tag
|
||||||
) and not hex_common.is_idef_parser_enabled(tag)
|
) and not hex_common.is_idef_parser_enabled(tag)
|
||||||
if has_generated_helper and "A_SCALAR_LOAD" in hex_common.attribdict[tag]:
|
|
||||||
f.write(" ctx->need_pkt_has_store_s1 = true;\n")
|
|
||||||
|
|
||||||
## Mark HVX instructions with generated helpers
|
## Mark HVX instructions with generated helpers
|
||||||
if (has_generated_helper and
|
if (has_generated_helper and
|
||||||
|
@ -303,7 +303,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
|
|||||||
if hex_common.need_slot(tag):
|
if hex_common.need_slot(tag):
|
||||||
if i > 0:
|
if i > 0:
|
||||||
f.write(", ")
|
f.write(", ")
|
||||||
f.write("uint32_t slot")
|
f.write("uint32_t slotval")
|
||||||
i += 1
|
i += 1
|
||||||
if hex_common.need_part1(tag):
|
if hex_common.need_part1(tag):
|
||||||
if i > 0:
|
if i > 0:
|
||||||
@ -331,6 +331,11 @@ def gen_helper_function(f, tag, tagregs, tagimms):
|
|||||||
else:
|
else:
|
||||||
print("Bad register parse: ", regtype, regid, toss, numregs)
|
print("Bad register parse: ", regtype, regid, toss, numregs)
|
||||||
|
|
||||||
|
if hex_common.need_slot(tag):
|
||||||
|
if "A_LOAD" in hex_common.attribdict[tag]:
|
||||||
|
f.write(" bool pkt_has_store_s1 = slotval & 0x1;\n")
|
||||||
|
f.write(" uint32_t slot = slotval >> 1;\n")
|
||||||
|
|
||||||
if "A_FPOP" in hex_common.attribdict[tag]:
|
if "A_FPOP" in hex_common.attribdict[tag]:
|
||||||
f.write(" arch_fpop_start(env);\n")
|
f.write(" arch_fpop_start(env);\n")
|
||||||
|
|
||||||
|
@ -556,7 +556,7 @@ def gen_tcg_func(f, tag, regs, imms):
|
|||||||
if hex_common.need_part1(tag):
|
if hex_common.need_part1(tag):
|
||||||
f.write(" TCGv part1 = tcg_constant_tl(insn->part1);\n")
|
f.write(" TCGv part1 = tcg_constant_tl(insn->part1);\n")
|
||||||
if hex_common.need_slot(tag):
|
if hex_common.need_slot(tag):
|
||||||
f.write(" TCGv slot = tcg_constant_tl(insn->slot);\n")
|
f.write(" TCGv slotval = gen_slotval(ctx);\n")
|
||||||
if hex_common.need_PC(tag):
|
if hex_common.need_PC(tag):
|
||||||
f.write(" TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
|
f.write(" TCGv PC = tcg_constant_tl(ctx->pkt->pc);\n")
|
||||||
if hex_common.helper_needs_next_PC(tag):
|
if hex_common.helper_needs_next_PC(tag):
|
||||||
@ -606,7 +606,7 @@ def gen_tcg_func(f, tag, regs, imms):
|
|||||||
if hex_common.helper_needs_next_PC(tag):
|
if hex_common.helper_needs_next_PC(tag):
|
||||||
f.write(", next_PC")
|
f.write(", next_PC")
|
||||||
if hex_common.need_slot(tag):
|
if hex_common.need_slot(tag):
|
||||||
f.write(", slot")
|
f.write(", slotval")
|
||||||
if hex_common.need_part1(tag):
|
if hex_common.need_part1(tag):
|
||||||
f.write(", part1")
|
f.write(", part1")
|
||||||
f.write(");\n")
|
f.write(");\n")
|
||||||
|
@ -398,6 +398,14 @@ static inline void gen_store_conditional8(DisasContext *ctx,
|
|||||||
tcg_gen_movi_tl(hex_llsc_addr, ~0);
|
tcg_gen_movi_tl(hex_llsc_addr, ~0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_HEXAGON_IDEF_PARSER
|
||||||
|
static TCGv gen_slotval(DisasContext *ctx)
|
||||||
|
{
|
||||||
|
int slotval = (ctx->pkt->pkt_has_store_s1 & 1) | (ctx->insn->slot << 1);
|
||||||
|
return tcg_constant_tl(slotval);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot)
|
void gen_store32(TCGv vaddr, TCGv src, int width, uint32_t slot)
|
||||||
{
|
{
|
||||||
tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
|
tcg_gen_mov_tl(hex_store_addr[slot], vaddr);
|
||||||
|
@ -247,9 +247,10 @@ def is_new_val(regtype, regid, tag):
|
|||||||
|
|
||||||
def need_slot(tag):
|
def need_slot(tag):
|
||||||
if (
|
if (
|
||||||
("A_CONDEXEC" in attribdict[tag] and "A_JUMP" not in attribdict[tag])
|
"A_CVI_SCATTER" not in attribdict[tag]
|
||||||
or "A_STORE" in attribdict[tag]
|
and "A_CVI_GATHER" not in attribdict[tag]
|
||||||
or "A_LOAD" in attribdict[tag]
|
and ("A_STORE" in attribdict[tag]
|
||||||
|
or "A_LOAD" in attribdict[tag])
|
||||||
):
|
):
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
|
@ -173,14 +173,14 @@
|
|||||||
#define MEM_STORE8(VA, DATA, SLOT) \
|
#define MEM_STORE8(VA, DATA, SLOT) \
|
||||||
MEM_STORE8_FUNC(DATA)(cpu_env, VA, DATA, SLOT)
|
MEM_STORE8_FUNC(DATA)(cpu_env, VA, DATA, SLOT)
|
||||||
#else
|
#else
|
||||||
#define MEM_LOAD1s(VA) ((int8_t)mem_load1(env, slot, VA))
|
#define MEM_LOAD1s(VA) ((int8_t)mem_load1(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD1u(VA) ((uint8_t)mem_load1(env, slot, VA))
|
#define MEM_LOAD1u(VA) ((uint8_t)mem_load1(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD2s(VA) ((int16_t)mem_load2(env, slot, VA))
|
#define MEM_LOAD2s(VA) ((int16_t)mem_load2(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD2u(VA) ((uint16_t)mem_load2(env, slot, VA))
|
#define MEM_LOAD2u(VA) ((uint16_t)mem_load2(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD4s(VA) ((int32_t)mem_load4(env, slot, VA))
|
#define MEM_LOAD4s(VA) ((int32_t)mem_load4(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD4u(VA) ((uint32_t)mem_load4(env, slot, VA))
|
#define MEM_LOAD4u(VA) ((uint32_t)mem_load4(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD8s(VA) ((int64_t)mem_load8(env, slot, VA))
|
#define MEM_LOAD8s(VA) ((int64_t)mem_load8(env, pkt_has_store_s1, slot, VA))
|
||||||
#define MEM_LOAD8u(VA) ((uint64_t)mem_load8(env, slot, VA))
|
#define MEM_LOAD8u(VA) ((uint64_t)mem_load8(env, pkt_has_store_s1, slot, VA))
|
||||||
|
|
||||||
#define MEM_STORE1(VA, DATA, SLOT) log_store32(env, VA, DATA, 1, SLOT)
|
#define MEM_STORE1(VA, DATA, SLOT) log_store32(env, VA, DATA, 1, SLOT)
|
||||||
#define MEM_STORE2(VA, DATA, SLOT) log_store32(env, VA, DATA, 2, SLOT)
|
#define MEM_STORE2(VA, DATA, SLOT) log_store32(env, VA, DATA, 2, SLOT)
|
||||||
|
@ -567,41 +567,45 @@ void HELPER(probe_pkt_scalar_hvx_stores)(CPUHexagonState *env, int mask)
|
|||||||
* If the load is in slot 0 and there is a store in slot1 (that
|
* If the load is in slot 0 and there is a store in slot1 (that
|
||||||
* wasn't cancelled), we have to do the store first.
|
* wasn't cancelled), we have to do the store first.
|
||||||
*/
|
*/
|
||||||
static void check_noshuf(CPUHexagonState *env, uint32_t slot,
|
static void check_noshuf(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
target_ulong vaddr, int size)
|
uint32_t slot, target_ulong vaddr, int size)
|
||||||
{
|
{
|
||||||
if (slot == 0 && env->pkt_has_store_s1 &&
|
if (slot == 0 && pkt_has_store_s1 &&
|
||||||
((env->slot_cancelled & (1 << 1)) == 0)) {
|
((env->slot_cancelled & (1 << 1)) == 0)) {
|
||||||
HELPER(probe_noshuf_load)(env, vaddr, size, MMU_USER_IDX);
|
HELPER(probe_noshuf_load)(env, vaddr, size, MMU_USER_IDX);
|
||||||
HELPER(commit_store)(env, 1);
|
HELPER(commit_store)(env, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, target_ulong vaddr)
|
uint8_t mem_load1(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
|
uint32_t slot, target_ulong vaddr)
|
||||||
{
|
{
|
||||||
uintptr_t ra = GETPC();
|
uintptr_t ra = GETPC();
|
||||||
check_noshuf(env, slot, vaddr, 1);
|
check_noshuf(env, pkt_has_store_s1, slot, vaddr, 1);
|
||||||
return cpu_ldub_data_ra(env, vaddr, ra);
|
return cpu_ldub_data_ra(env, vaddr, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, target_ulong vaddr)
|
uint16_t mem_load2(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
|
uint32_t slot, target_ulong vaddr)
|
||||||
{
|
{
|
||||||
uintptr_t ra = GETPC();
|
uintptr_t ra = GETPC();
|
||||||
check_noshuf(env, slot, vaddr, 2);
|
check_noshuf(env, pkt_has_store_s1, slot, vaddr, 2);
|
||||||
return cpu_lduw_data_ra(env, vaddr, ra);
|
return cpu_lduw_data_ra(env, vaddr, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, target_ulong vaddr)
|
uint32_t mem_load4(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
|
uint32_t slot, target_ulong vaddr)
|
||||||
{
|
{
|
||||||
uintptr_t ra = GETPC();
|
uintptr_t ra = GETPC();
|
||||||
check_noshuf(env, slot, vaddr, 4);
|
check_noshuf(env, pkt_has_store_s1, slot, vaddr, 4);
|
||||||
return cpu_ldl_data_ra(env, vaddr, ra);
|
return cpu_ldl_data_ra(env, vaddr, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, target_ulong vaddr)
|
uint64_t mem_load8(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
|
uint32_t slot, target_ulong vaddr)
|
||||||
{
|
{
|
||||||
uintptr_t ra = GETPC();
|
uintptr_t ra = GETPC();
|
||||||
check_noshuf(env, slot, vaddr, 8);
|
check_noshuf(env, pkt_has_store_s1, slot, vaddr, 8);
|
||||||
return cpu_ldq_data_ra(env, vaddr, ra);
|
return cpu_ldq_data_ra(env, vaddr, ra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +19,14 @@
|
|||||||
#define HEXAGON_OP_HELPER_H
|
#define HEXAGON_OP_HELPER_H
|
||||||
|
|
||||||
/* Misc functions */
|
/* Misc functions */
|
||||||
uint8_t mem_load1(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
|
uint8_t mem_load1(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
uint16_t mem_load2(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
|
uint32_t slot, target_ulong vaddr);
|
||||||
uint32_t mem_load4(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
|
uint16_t mem_load2(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
uint64_t mem_load8(CPUHexagonState *env, uint32_t slot, target_ulong vaddr);
|
uint32_t slot, target_ulong vaddr);
|
||||||
|
uint32_t mem_load4(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
|
uint32_t slot, target_ulong vaddr);
|
||||||
|
uint64_t mem_load8(CPUHexagonState *env, bool pkt_has_store_s1,
|
||||||
|
uint32_t slot, target_ulong vaddr);
|
||||||
|
|
||||||
void log_store64(CPUHexagonState *env, target_ulong addr,
|
void log_store64(CPUHexagonState *env, target_ulong addr,
|
||||||
int64_t val, int width, int slot);
|
int64_t val, int width, int slot);
|
||||||
|
@ -463,7 +463,6 @@ 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->need_pkt_has_store_s1 = false;
|
|
||||||
ctx->has_hvx_helper = false;
|
ctx->has_hvx_helper = 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];
|
||||||
@ -519,10 +518,6 @@ static void gen_start_packet(DisasContext *ctx)
|
|||||||
|
|
||||||
analyze_packet(ctx);
|
analyze_packet(ctx);
|
||||||
|
|
||||||
if (ctx->need_pkt_has_store_s1) {
|
|
||||||
tcg_gen_movi_tl(hex_pkt_has_store_s1, pkt->pkt_has_store_s1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pregs_written is used both in the analyze phase as well as the code
|
* pregs_written is used both in the analyze phase as well as the code
|
||||||
* gen phase, so clear it again.
|
* gen phase, so clear it again.
|
||||||
@ -1207,8 +1202,6 @@ void hexagon_translate_init(void)
|
|||||||
offsetof(CPUHexagonState, slot_cancelled), "slot_cancelled");
|
offsetof(CPUHexagonState, slot_cancelled), "slot_cancelled");
|
||||||
hex_branch_taken = tcg_global_mem_new(cpu_env,
|
hex_branch_taken = tcg_global_mem_new(cpu_env,
|
||||||
offsetof(CPUHexagonState, branch_taken), "branch_taken");
|
offsetof(CPUHexagonState, branch_taken), "branch_taken");
|
||||||
hex_pkt_has_store_s1 = tcg_global_mem_new(cpu_env,
|
|
||||||
offsetof(CPUHexagonState, pkt_has_store_s1), "pkt_has_store_s1");
|
|
||||||
hex_dczero_addr = tcg_global_mem_new(cpu_env,
|
hex_dczero_addr = tcg_global_mem_new(cpu_env,
|
||||||
offsetof(CPUHexagonState, dczero_addr), "dczero_addr");
|
offsetof(CPUHexagonState, dczero_addr), "dczero_addr");
|
||||||
hex_llsc_addr = tcg_global_mem_new(cpu_env,
|
hex_llsc_addr = tcg_global_mem_new(cpu_env,
|
||||||
|
@ -66,7 +66,6 @@ typedef struct DisasContext {
|
|||||||
TCGCond branch_cond;
|
TCGCond branch_cond;
|
||||||
target_ulong branch_dest;
|
target_ulong branch_dest;
|
||||||
bool is_tight_loop;
|
bool is_tight_loop;
|
||||||
bool need_pkt_has_store_s1;
|
|
||||||
bool short_circuit;
|
bool short_circuit;
|
||||||
bool has_hvx_helper;
|
bool has_hvx_helper;
|
||||||
TCGv new_value[TOTAL_PER_THREAD_REGS];
|
TCGv new_value[TOTAL_PER_THREAD_REGS];
|
||||||
|
Loading…
Reference in New Issue
Block a user