tcg: Define INSN_START_WORDS as constant 3

Use the same value for all targets.

Rename TARGET_INSN_START_WORDS and do not depend on
TARGET_INSN_START_EXTRA_WORDS.
Remove TCGContext.insn_start_words.

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-04-30 13:57:30 -07:00
parent c1be135ad5
commit e1d8fabc20
9 changed files with 45 additions and 38 deletions

View file

@ -120,7 +120,7 @@ static int64_t decode_sleb128(const uint8_t **pp)
/* Encode the data collected about the instructions while compiling TB. /* Encode the data collected about the instructions while compiling TB.
Place the data at BLOCK, and return the number of bytes consumed. Place the data at BLOCK, and return the number of bytes consumed.
The logical table consists of TARGET_INSN_START_WORDS target_ulong's, The logical table consists of INSN_START_WORDS uint64_t's,
which come from the target's insn_start data, followed by a uintptr_t which come from the target's insn_start data, followed by a uintptr_t
which comes from the host pc of the end of the code implementing the insn. which comes from the host pc of the end of the code implementing the insn.
@ -140,13 +140,13 @@ static int encode_search(TranslationBlock *tb, uint8_t *block)
for (i = 0, n = tb->icount; i < n; ++i) { for (i = 0, n = tb->icount; i < n; ++i) {
uint64_t prev, curr; uint64_t prev, curr;
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { for (j = 0; j < INSN_START_WORDS; ++j) {
if (i == 0) { if (i == 0) {
prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb->pc : 0); prev = (!(tb_cflags(tb) & CF_PCREL) && j == 0 ? tb->pc : 0);
} else { } else {
prev = insn_data[(i - 1) * TARGET_INSN_START_WORDS + j]; prev = insn_data[(i - 1) * INSN_START_WORDS + j];
} }
curr = insn_data[i * TARGET_INSN_START_WORDS + j]; curr = insn_data[i * INSN_START_WORDS + j];
p = encode_sleb128(p, curr - prev); p = encode_sleb128(p, curr - prev);
} }
prev = (i == 0 ? 0 : insn_end_off[i - 1]); prev = (i == 0 ? 0 : insn_end_off[i - 1]);
@ -178,7 +178,7 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
return -1; return -1;
} }
memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS); memset(data, 0, sizeof(uint64_t) * INSN_START_WORDS);
if (!(tb_cflags(tb) & CF_PCREL)) { if (!(tb_cflags(tb) & CF_PCREL)) {
data[0] = tb->pc; data[0] = tb->pc;
} }
@ -188,7 +188,7 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
* at which the end of the insn exceeds host_pc. * at which the end of the insn exceeds host_pc.
*/ */
for (i = 0; i < num_insns; ++i) { for (i = 0; i < num_insns; ++i) {
for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { for (j = 0; j < INSN_START_WORDS; ++j) {
data[j] += decode_sleb128(&p); data[j] += decode_sleb128(&p);
} }
iter_pc += decode_sleb128(&p); iter_pc += decode_sleb128(&p);
@ -206,7 +206,7 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc,
void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
uintptr_t host_pc) uintptr_t host_pc)
{ {
uint64_t data[TARGET_INSN_START_WORDS]; uint64_t data[INSN_START_WORDS];
int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data);
if (insns_left < 0) { if (insns_left < 0) {
@ -349,7 +349,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s)
tcg_ctx->page_mask = TARGET_PAGE_MASK; tcg_ctx->page_mask = TARGET_PAGE_MASK;
tcg_ctx->tlb_dyn_max_bits = CPU_TLB_DYN_MAX_BITS; tcg_ctx->tlb_dyn_max_bits = CPU_TLB_DYN_MAX_BITS;
#endif #endif
tcg_ctx->insn_start_words = TARGET_INSN_START_WORDS;
tcg_ctx->guest_mo = cpu->cc->tcg_ops->guest_default_memory_order; tcg_ctx->guest_mo = cpu->cc->tcg_ops->guest_default_memory_order;
restart_translate: restart_translate:
@ -457,7 +456,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s)
fprintf(logfile, "OUT: [size=%d]\n", gen_code_size); fprintf(logfile, "OUT: [size=%d]\n", gen_code_size);
fprintf(logfile, fprintf(logfile,
" -- guest addr 0x%016" PRIx64 " + tb prologue\n", " -- guest addr 0x%016" PRIx64 " + tb prologue\n",
tcg_ctx->gen_insn_data[insn * TARGET_INSN_START_WORDS]); tcg_ctx->gen_insn_data[insn * INSN_START_WORDS]);
chunk_start = tcg_ctx->gen_insn_end_off[insn]; chunk_start = tcg_ctx->gen_insn_end_off[insn];
disas(logfile, tb->tc.ptr, chunk_start); disas(logfile, tb->tc.ptr, chunk_start);
@ -470,7 +469,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, TCGTBCPUState s)
size_t chunk_end = tcg_ctx->gen_insn_end_off[insn]; size_t chunk_end = tcg_ctx->gen_insn_end_off[insn];
if (chunk_end > chunk_start) { if (chunk_end > chunk_start) {
fprintf(logfile, " -- guest addr 0x%016" PRIx64 "\n", fprintf(logfile, " -- guest addr 0x%016" PRIx64 "\n",
tcg_ctx->gen_insn_data[insn * TARGET_INSN_START_WORDS]); tcg_ctx->gen_insn_data[insn * INSN_START_WORDS]);
disas(logfile, tb->tc.ptr + chunk_start, disas(logfile, tb->tc.ptr + chunk_start,
chunk_end - chunk_start); chunk_end - chunk_start);
chunk_start = chunk_end; chunk_start = chunk_end;

View file

@ -1,13 +1,12 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
/* /*
* Define TARGET_INSN_START_WORDS * Define INSN_START_WORDS
* Copyright (c) 2008 Fabrice Bellard * Copyright (c) 2008 Fabrice Bellard
*/ */
#ifndef TARGET_INSN_START_WORDS #ifndef TCG_INSN_START_WORDS
#define TCG_INSN_START_WORDS
#include "cpu-param.h" #define INSN_START_WORDS 3
# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS) #endif /* TCG_INSN_START_WORDS */
#endif /* TARGET_INSN_START_WORDS */

View file

@ -9,6 +9,7 @@
#define TCG_TCG_OP_H #define TCG_TCG_OP_H
#include "tcg/tcg-op-common.h" #include "tcg/tcg-op-common.h"
#include "tcg/insn-start-words.h"
#include "exec/target_long.h" #include "exec/target_long.h"
#ifndef TARGET_LONG_BITS #ifndef TARGET_LONG_BITS
@ -23,24 +24,34 @@
# error # error
#endif #endif
#if INSN_START_WORDS != 3
# error Mismatch with insn-start-words.h
#endif
#if TARGET_INSN_START_EXTRA_WORDS == 0 #if TARGET_INSN_START_EXTRA_WORDS == 0
static inline void tcg_gen_insn_start(target_ulong pc) static inline void tcg_gen_insn_start(target_ulong pc)
{ {
TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 64 / TCG_TARGET_REG_BITS); TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
tcg_set_insn_start_param(op, 0, pc); tcg_set_insn_start_param(op, 0, pc);
tcg_set_insn_start_param(op, 1, 0);
tcg_set_insn_start_param(op, 2, 0);
} }
#elif TARGET_INSN_START_EXTRA_WORDS == 1 #elif TARGET_INSN_START_EXTRA_WORDS == 1
static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1) static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1)
{ {
TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 2 * 64 / TCG_TARGET_REG_BITS); TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
tcg_set_insn_start_param(op, 0, pc); tcg_set_insn_start_param(op, 0, pc);
tcg_set_insn_start_param(op, 1, a1); tcg_set_insn_start_param(op, 1, a1);
tcg_set_insn_start_param(op, 2, 0);
} }
#elif TARGET_INSN_START_EXTRA_WORDS == 2 #elif TARGET_INSN_START_EXTRA_WORDS == 2
static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1, static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
target_ulong a2) target_ulong a2)
{ {
TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 3 * 64 / TCG_TARGET_REG_BITS); TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
tcg_set_insn_start_param(op, 0, pc); tcg_set_insn_start_param(op, 0, pc);
tcg_set_insn_start_param(op, 1, a1); tcg_set_insn_start_param(op, 1, a1);
tcg_set_insn_start_param(op, 2, a2); tcg_set_insn_start_param(op, 2, a2);

View file

@ -114,8 +114,7 @@ DEF(extrh_i64_i32, 1, 1, 0, 0)
#define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2) #define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2)
/* There are tcg_ctx->insn_start_words here, not just one. */ DEF(insn_start, 0, 0, DATA64_ARGS * INSN_START_WORDS, TCG_OPF_NOT_PRESENT)
DEF(insn_start, 0, 0, DATA64_ARGS, TCG_OPF_NOT_PRESENT)
DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)

View file

@ -34,6 +34,7 @@
#include "tcg-target-reg-bits.h" #include "tcg-target-reg-bits.h"
#include "tcg-target.h" #include "tcg-target.h"
#include "tcg/tcg-cond.h" #include "tcg/tcg-cond.h"
#include "tcg/insn-start-words.h"
#include "tcg/debug-assert.h" #include "tcg/debug-assert.h"
/* XXX: make safe guess about sizes */ /* XXX: make safe guess about sizes */
@ -359,7 +360,6 @@ struct TCGContext {
int page_mask; int page_mask;
uint8_t page_bits; uint8_t page_bits;
uint8_t tlb_dyn_max_bits; uint8_t tlb_dyn_max_bits;
uint8_t insn_start_words;
TCGBar guest_mo; TCGBar guest_mo;
TCGRegSet reserved_regs; TCGRegSet reserved_regs;
@ -582,18 +582,19 @@ static inline TCGv_vec temp_tcgv_vec(TCGTemp *t)
return (TCGv_vec)temp_tcgv_i32(t); return (TCGv_vec)temp_tcgv_i32(t);
} }
static inline TCGArg tcg_get_insn_param(TCGOp *op, int arg) static inline TCGArg tcg_get_insn_param(TCGOp *op, unsigned arg)
{ {
return op->args[arg]; return op->args[arg];
} }
static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v) static inline void tcg_set_insn_param(TCGOp *op, unsigned arg, TCGArg v)
{ {
op->args[arg] = v; op->args[arg] = v;
} }
static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg) static inline uint64_t tcg_get_insn_start_param(TCGOp *op, unsigned arg)
{ {
tcg_debug_assert(arg < INSN_START_WORDS);
if (TCG_TARGET_REG_BITS == 64) { if (TCG_TARGET_REG_BITS == 64) {
return tcg_get_insn_param(op, arg); return tcg_get_insn_param(op, arg);
} else { } else {
@ -602,8 +603,9 @@ static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg)
} }
} }
static inline void tcg_set_insn_start_param(TCGOp *op, int arg, uint64_t v) static inline void tcg_set_insn_start_param(TCGOp *op, unsigned arg, uint64_t v)
{ {
tcg_debug_assert(arg < INSN_START_WORDS);
if (TCG_TARGET_REG_BITS == 64) { if (TCG_TARGET_REG_BITS == 64) {
tcg_set_insn_param(op, arg, v); tcg_set_insn_param(op, arg, v);
} else { } else {

View file

@ -526,7 +526,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
static inline target_ulong get_memio_eip(CPUX86State *env) static inline target_ulong get_memio_eip(CPUX86State *env)
{ {
#ifdef CONFIG_TCG #ifdef CONFIG_TCG
uint64_t data[TARGET_INSN_START_WORDS]; uint64_t data[INSN_START_WORDS];
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {

View file

@ -218,7 +218,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
{ {
OpenRISCCPU *cpu = env_archcpu(env); OpenRISCCPU *cpu = env_archcpu(env);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
uint64_t data[TARGET_INSN_START_WORDS]; uint64_t data[INSN_START_WORDS];
MachineState *ms = MACHINE(qdev_get_machine()); MachineState *ms = MACHINE(qdev_get_machine());
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
int idx; int idx;

View file

@ -313,7 +313,7 @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
const void *start) const void *start)
{ {
struct debuginfo_query *q; struct debuginfo_query *q;
size_t insn, start_words; size_t insn;
uint64_t *gen_insn_data; uint64_t *gen_insn_data;
if (!perfmap && !jitdump) { if (!perfmap && !jitdump) {
@ -329,11 +329,10 @@ void perf_report_code(uint64_t guest_pc, TranslationBlock *tb,
/* Query debuginfo for each guest instruction. */ /* Query debuginfo for each guest instruction. */
gen_insn_data = tcg_ctx->gen_insn_data; gen_insn_data = tcg_ctx->gen_insn_data;
start_words = tcg_ctx->insn_start_words;
for (insn = 0; insn < tb->icount; insn++) { for (insn = 0; insn < tb->icount; insn++) {
/* FIXME: This replicates the restore_state_to_opc() logic. */ /* FIXME: This replicates the restore_state_to_opc() logic. */
q[insn].address = gen_insn_data[insn * start_words + 0]; q[insn].address = gen_insn_data[insn * INSN_START_WORDS + 0];
if (tb_cflags(tb) & CF_PCREL) { if (tb_cflags(tb) & CF_PCREL) {
q[insn].address |= (guest_pc & qemu_target_page_mask()); q[insn].address |= (guest_pc & qemu_target_page_mask());
} }

View file

@ -1989,7 +1989,6 @@ void tcg_func_start(TCGContext *s)
QSIMPLEQ_INIT(&s->labels); QSIMPLEQ_INIT(&s->labels);
tcg_debug_assert(s->addr_type <= TCG_TYPE_REG); tcg_debug_assert(s->addr_type <= TCG_TYPE_REG);
tcg_debug_assert(s->insn_start_words > 0);
} }
static TCGTemp *tcg_temp_alloc(TCGContext *s) static TCGTemp *tcg_temp_alloc(TCGContext *s)
@ -2943,7 +2942,7 @@ void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
nb_oargs = 0; nb_oargs = 0;
col += ne_fprintf(f, "\n ----"); col += ne_fprintf(f, "\n ----");
for (i = 0, k = s->insn_start_words; i < k; ++i) { for (i = 0, k = INSN_START_WORDS; i < k; ++i) {
col += ne_fprintf(f, " %016" PRIx64, col += ne_fprintf(f, " %016" PRIx64,
tcg_get_insn_start_param(op, i)); tcg_get_insn_start_param(op, i));
} }
@ -6835,7 +6834,7 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
{ {
int i, start_words, num_insns; int i, num_insns;
TCGOp *op; TCGOp *op;
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP) if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
@ -6925,9 +6924,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
QSIMPLEQ_INIT(&s->ldst_labels); QSIMPLEQ_INIT(&s->ldst_labels);
s->pool_labels = NULL; s->pool_labels = NULL;
start_words = s->insn_start_words;
s->gen_insn_data = s->gen_insn_data =
tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * start_words); tcg_malloc(sizeof(uint64_t) * s->gen_tb->icount * INSN_START_WORDS);
tcg_out_tb_start(s); tcg_out_tb_start(s);
@ -6969,8 +6967,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
assert(s->gen_insn_end_off[num_insns] == off); assert(s->gen_insn_end_off[num_insns] == off);
} }
num_insns++; num_insns++;
for (i = 0; i < start_words; ++i) { for (i = 0; i < INSN_START_WORDS; ++i) {
s->gen_insn_data[num_insns * start_words + i] = s->gen_insn_data[num_insns * INSN_START_WORDS + i] =
tcg_get_insn_start_param(op, i); tcg_get_insn_start_param(op, i);
} }
break; break;