diff --git a/qemu/include/exec/gen-icount.h b/qemu/include/exec/gen-icount.h index b9500a8d..b6032fda 100644 --- a/qemu/include/exec/gen-icount.h +++ b/qemu/include/exec/gen-icount.h @@ -63,7 +63,8 @@ static inline void gen_tb_end(TCGContext *tcg_ctx, TranslationBlock *tb, int num #endif /* Terminate the linked list. */ - tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].next = -1; + tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].next = 0; + } #if 0 diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index f70c2cb3..8f2463fa 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -11424,7 +11424,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb) if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { // save block address to see if we need to patch block size later env->uc->block_addr = pc_start; - env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } else { env->uc->size_arg = -1; diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c index bb33965b..eaac67f0 100644 --- a/qemu/target-arm/translate.c +++ b/qemu/target-arm/translate.c @@ -11918,7 +11918,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { // save block address to see if we need to patch block size later env->uc->block_addr = pc_start; - env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } else { env->uc->size_arg = -1; diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 6e0c86b1..da6fd95e 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -4952,7 +4952,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, TCGv cpu_T1 = tcg_ctx->cpu_T1; TCGv *cpu_regs = tcg_ctx->cpu_regs; TCGv *cpu_seg_base = tcg_ctx->cpu_seg_base; - TCGArg* save_opparam_ptr = tcg_ctx->gen_opparam_buf + tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + TCGArg* save_opparam_ptr = tcg_ctx->gen_opparam_buf + tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; bool cc_op_dirty = s->cc_op_dirty; bool changed_cc_op = false; @@ -9062,7 +9062,7 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb) // Unicorn: trace this block on request // Only hook this block if the previous block was not truncated due to space if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { - int arg_i = tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + int arg_i = tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; env->uc->block_addr = pc_start; env->uc->size_arg = arg_i + 1; gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); diff --git a/qemu/target-m68k/translate.c b/qemu/target-m68k/translate.c index bb185732..04a179b7 100644 --- a/qemu/target-m68k/translate.c +++ b/qemu/target-m68k/translate.c @@ -3103,7 +3103,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { // save block address to see if we need to patch block size later env->uc->block_addr = pc_start; - env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } else { env->uc->size_arg = -1; diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 5264ad73..91856f8f 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -20042,7 +20042,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb) // Only hook this block if it is not broken from previous translation due to // full translation cache if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { - int arg_i = tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + int arg_i = tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; // save block address to see if we need to patch block size later env->uc->block_addr = pc_start; env->uc->size_arg = arg_i + 1; diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index db7f7616..a5bea40f 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -5805,7 +5805,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { // save block address to see if we need to patch block size later env->uc->block_addr = pc_start; - env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_last_op_idx].args; + env->uc->size_arg = tcg_ctx->gen_op_buf[tcg_ctx->gen_op_buf[0].prev].args; gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } diff --git a/qemu/tcg/optimize.c b/qemu/tcg/optimize.c index 69eeb5e8..ae009d22 100644 --- a/qemu/tcg/optimize.c +++ b/qemu/tcg/optimize.c @@ -103,11 +103,7 @@ static TCGOp *insert_op_before(TCGContext *s, TCGOp *old_op, new_op = &s->gen_op_buf[oi]; *new_op = new_opp; - if (prev >= 0) { - s->gen_op_buf[prev].next = oi; - } else { - s->gen_first_op_idx = oi; - } + s->gen_op_buf[prev].next = oi; old_op->prev = oi; return new_op; @@ -595,7 +591,7 @@ void tcg_optimize(TCGContext *s) nb_globals = s->nb_globals; reset_all_temps(s, nb_temps); - for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) { + for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) { tcg_target_ulong mask, partmask, affected; int nb_oargs, nb_iargs, i; TCGArg tmp; diff --git a/qemu/tcg/tcg-op.c b/qemu/tcg/tcg-op.c index b6563a00..19fd5f5d 100644 --- a/qemu/tcg/tcg-op.c +++ b/qemu/tcg/tcg-op.c @@ -51,7 +51,7 @@ static void tcg_emit_op(TCGContext *ctx, TCGOpcode opc, int args) TCGOp op = {0}; tcg_debug_assert(oi < OPC_BUF_SIZE); - ctx->gen_last_op_idx = oi; + ctx->gen_op_buf[0].prev = oi; ctx->gen_next_op_idx = ni; op.opc = opc; diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 34fd359f..097da14e 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -432,9 +432,9 @@ void tcg_func_start(TCGContext *s) s->goto_tb_issue_mask = 0; #endif - s->gen_first_op_idx = 0; - s->gen_last_op_idx = -1; - s->gen_next_op_idx = 0; + s->gen_op_buf[0].next = 1; + s->gen_op_buf[0].prev = 0; + s->gen_next_op_idx = 1; s->gen_next_parm_idx = 0; s->be = tcg_malloc(s, sizeof(TCGBackendData)); @@ -858,7 +858,7 @@ void tcg_gen_callN(TCGContext *s, void *func, TCGArg ret, /* Make sure the calli field didn't overflow. */ tcg_debug_assert(s->gen_op_buf[i].calli == real_args); - s->gen_last_op_idx = i; + s->gen_op_buf[0].prev = i; s->gen_next_op_idx = i + 1; s->gen_next_parm_idx = pi; @@ -1066,7 +1066,7 @@ void tcg_dump_ops(TCGContext *s) TCGOp *op; int oi; - for (oi = s->gen_first_op_idx; oi >= 0; oi = op->next) { + for (oi = s->gen_op_buf[0].next; oi != 0; oi = op->next) { int i, k, nb_oargs, nb_iargs, nb_cargs; const TCGOpDef *def; const TCGArg *args; @@ -1078,7 +1078,7 @@ void tcg_dump_ops(TCGContext *s) args = &s->gen_opparam_buf[op->args]; if (c == INDEX_op_insn_start) { - printf("%s ----", oi != s->gen_first_op_idx ? "\n" : ""); + qemu_log("%s ----", oi != s->gen_op_buf[0].next ? "\n" : ""); for (i = 0; i < TARGET_INSN_START_WORDS; ++i) { target_ulong a; @@ -1088,7 +1088,7 @@ void tcg_dump_ops(TCGContext *s) #else a = args[i]; #endif - printf(" " TARGET_FMT_lx, a); + qemu_log(" " TARGET_FMT_lx, a); } } else if (c == INDEX_op_call) { /* variable number of arguments */ @@ -1097,12 +1097,12 @@ void tcg_dump_ops(TCGContext *s) nb_cargs = def->nb_cargs; /* function name, flags, out args */ - printf(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name, + qemu_log(" %s %s,$0x%" TCG_PRIlx ",$%d", def->name, tcg_find_helper(s, args[nb_oargs + nb_iargs]), args[nb_oargs + nb_iargs + 1], nb_oargs); for (i = 0; i < nb_oargs; i++) { - printf(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), - args[i])); + qemu_log(",%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + args[i])); } for (i = 0; i < nb_iargs; i++) { TCGArg arg = args[nb_oargs + i]; @@ -1110,10 +1110,10 @@ void tcg_dump_ops(TCGContext *s) if (arg != TCG_CALL_DUMMY_ARG) { t = tcg_get_arg_str_idx(s, buf, sizeof(buf), arg); } - printf(",%s", t); + qemu_log(",%s", t); } } else { - printf(" %s ", def->name); + qemu_log(" %s ", def->name); nb_oargs = def->nb_oargs; nb_iargs = def->nb_iargs; @@ -1122,16 +1122,16 @@ void tcg_dump_ops(TCGContext *s) k = 0; for (i = 0; i < nb_oargs; i++) { if (k != 0) { - printf(","); + qemu_log(","); } - printf("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); } for (i = 0; i < nb_iargs; i++) { if (k != 0) { - printf(","); + qemu_log(","); } - printf("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), + qemu_log("%s", tcg_get_arg_str_idx(s, buf, sizeof(buf), args[k++])); } switch (c) { @@ -1144,9 +1144,9 @@ void tcg_dump_ops(TCGContext *s) case INDEX_op_setcond_i64: case INDEX_op_movcond_i64: if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) { - printf(",%s", cond_name[args[k++]]); + qemu_log(",%s", cond_name[args[k++]]); } else { - printf(",$0x%" TCG_PRIlx, args[k++]); + qemu_log(",$0x%" TCG_PRIlx, args[k++]); } i = 1; break; @@ -1160,12 +1160,12 @@ void tcg_dump_ops(TCGContext *s) unsigned ix = get_mmuidx(oi); if (op & ~(MO_AMASK | MO_BSWAP | MO_SSIZE)) { - printf(",%s,%u", ldst_name[op], ix); + qemu_log(",$0x%x,%u", op, ix); } else { const char *s_al, *s_op; s_al = alignment_name[(op & MO_AMASK) >> MO_ASHIFT]; s_op = ldst_name[op & (MO_BSWAP | MO_SSIZE)]; - printf(",%s%s,%u", s_al, s_op, ix); + qemu_log(",%s%s,%u", s_al, s_op, ix); } i = 1; } @@ -1190,9 +1190,8 @@ void tcg_dump_ops(TCGContext *s) qemu_log("%s$0x%" TCG_PRIlx, k ? "," : "", args[k]); } } - printf("\n"); + qemu_log("\n"); } - printf("###########\n"); } /* we give more priority to constraints with less registers */ @@ -1345,18 +1344,13 @@ void tcg_op_remove(TCGContext *s, TCGOp *op) int next = op->next; int prev = op->prev; - if (next >= 0) { - s->gen_op_buf[next].prev = prev; - } else { - s->gen_last_op_idx = prev; - } - if (prev >= 0) { - s->gen_op_buf[prev].next = next; - } else { - s->gen_first_op_idx = next; - } + /* We should never attempt to remove the list terminator. */ + tcg_debug_assert(op != &s->gen_op_buf[0]); - memset(op, -1, sizeof(*op)); + s->gen_op_buf[next].prev = prev; + s->gen_op_buf[prev].next = next; + + memset(op, 0, sizeof(*op)); #ifdef CONFIG_PROFILER s->del_op_count++; @@ -1417,7 +1411,7 @@ static void tcg_liveness_analysis(TCGContext *s) mem_temps = tcg_malloc(s, s->nb_temps); tcg_la_func_end(s, dead_temps, mem_temps); - for (oi = s->gen_last_op_idx; oi >= 0; oi = oi_prev) { + for (oi = s->gen_op_buf[0].prev; oi != 0; oi = oi_prev) { int i, nb_iargs, nb_oargs; TCGOpcode opc_new, opc_new2; bool have_opc_new2; @@ -2399,7 +2393,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) { int n; - n = s->gen_last_op_idx + 1; + n = s->gen_op_buf[0].prev + 1; s->op_count += n; if (n > s->op_count_max) { s->op_count_max = n; @@ -2458,7 +2452,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) tcg_out_tb_init(s); num_insns = -1; - for (oi = s->gen_first_op_idx; oi >= 0; oi = oi_next) { + for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) { TCGOp * const op = &s->gen_op_buf[oi]; TCGArg * const args = &s->gen_opparam_buf[op->args]; TCGOpcode opc = op->opc; diff --git a/qemu/tcg/tcg.h b/qemu/tcg/tcg.h index 6afb28e5..2b4e23b6 100644 --- a/qemu/tcg/tcg.h +++ b/qemu/tcg/tcg.h @@ -592,17 +592,21 @@ typedef struct TCGOp { unsigned callo : 2; unsigned calli : 6; - /* Index of the arguments for this op, or -1 for zero-operand ops. */ - signed args : 16; + /* Index of the arguments for this op, or 0 for zero-operand ops. */ + unsigned args : 16; - /* Index of the prex/next op, or -1 for the end of the list. */ - signed prev : 16; - signed next : 16; + /* Index of the prev/next op, or 0 for the end of the list. */ + unsigned prev : 16; + unsigned next : 16; } TCGOp; -QEMU_BUILD_BUG_ON(NB_OPS > 0xff); -QEMU_BUILD_BUG_ON(OPC_BUF_SIZE >= 0x7fff); -QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE >= 0x7fff); +/* Make sure operands fit in the bitfields above. */ +QEMU_BUILD_BUG_ON(NB_OPS > (1 << 8)); +QEMU_BUILD_BUG_ON(OPC_BUF_SIZE > (1 << 16)); +QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE > (1 << 16)); + +/* Make sure that we don't overflow 64 bits without noticing. */ +QEMU_BUILD_BUG_ON(sizeof(TCGOp) > 8); /* pool based memory allocation */ @@ -780,8 +784,6 @@ struct TCGContext { int goto_tb_issue_mask; #endif - int gen_first_op_idx; - int gen_last_op_idx; int gen_next_op_idx; int gen_next_parm_idx;