Commit e0fb2c3d authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190426' into staging



Add tcg_gen_extract2_*.
Deal with overflow of TranslationBlocks.
Respect access_type in io_readx.

# gpg: Signature made Fri 26 Apr 2019 18:17:01 BST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-tcg-20190426:
  cputlb: Fix io_readx() to respect the access_type
  tcg/arm: Restrict constant pool displacement to 12 bits
  tcg/ppc: Allow the constant pool to overflow at 32k
  tcg: Restart TB generation after out-of-line ldst overflow
  tcg: Restart TB generation after constant pool overflow
  tcg: Restart TB generation after relocation overflow
  tcg: Restart after TB code generation overflow
  tcg: Hoist max_insns computation to tb_gen_code
  tcg/aarch64: Support INDEX_op_extract2_{i32,i64}
  tcg/arm: Support INDEX_op_extract2_i32
  tcg/i386: Support INDEX_op_extract2_{i32,i64}
  tcg: Use extract2 in tcg_gen_deposit_{i32,i64}
  tcg: Use deposit and extract2 in tcg_gen_shifti_i64
  tcg: Add INDEX_op_extract2_{i32,i64}
  tcg: Implement tcg_gen_extract2_{i32,i64}

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 9ec34ecc ef5dae68
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -878,10 +878,11 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
        CPUTLBEntry *entry;
        target_ulong tlb_addr;

        tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
        tlb_fill(cpu, addr, size, access_type, mmu_idx, retaddr);

        entry = tlb_entry(env, mmu_idx, addr);
        tlb_addr = entry->addr_read;
        tlb_addr = (access_type == MMU_DATA_LOAD ?
                    entry->addr_read : entry->addr_code);
        if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
            /* RAM access */
            uintptr_t haddr = addr + entry->addend;
+45 −8
Original line number Diff line number Diff line
@@ -1674,7 +1674,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    tb_page_addr_t phys_pc, phys_page2;
    target_ulong virt_page2;
    tcg_insn_unit *gen_code_buf;
    int gen_code_size, search_size;
    int gen_code_size, search_size, max_insns;
#ifdef CONFIG_PROFILER
    TCGProfile *prof = &tcg_ctx->prof;
    int64_t ti;
@@ -1692,6 +1692,17 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    cflags &= ~CF_CLUSTER_MASK;
    cflags |= cpu->cluster_index << CF_CLUSTER_SHIFT;

    max_insns = cflags & CF_COUNT_MASK;
    if (max_insns == 0) {
        max_insns = CF_COUNT_MASK;
    }
    if (max_insns > TCG_MAX_INSNS) {
        max_insns = TCG_MAX_INSNS;
    }
    if (cpu->singlestep_enabled || singlestep) {
        max_insns = 1;
    }

 buffer_overflow:
    tb = tb_alloc(pc);
    if (unlikely(!tb)) {
@@ -1711,6 +1722,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    tb->cflags = cflags;
    tb->trace_vcpu_dstate = *cpu->trace_dstate;
    tcg_ctx->tb_cflags = cflags;
 tb_overflow:

#ifdef CONFIG_PROFILER
    /* includes aborted translations because of exceptions */
@@ -1721,7 +1733,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    tcg_func_start(tcg_ctx);

    tcg_ctx->cpu = ENV_GET_CPU(env);
    gen_intermediate_code(cpu, tb);
    gen_intermediate_code(cpu, tb, max_insns);
    tcg_ctx->cpu = NULL;

    trace_translate_block(tb, tb->pc, tb->tc.ptr);
@@ -1744,14 +1756,39 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
    ti = profile_getclock();
#endif

    /* ??? Overflow could be handled better here.  In particular, we
       don't need to re-do gen_intermediate_code, nor should we re-do
       the tcg optimization currently hidden inside tcg_gen_code.  All
       that should be required is to flush the TBs, allocate a new TB,
       re-initialize it per above, and re-do the actual code generation.  */
    gen_code_size = tcg_gen_code(tcg_ctx, tb);
    if (unlikely(gen_code_size < 0)) {
        switch (gen_code_size) {
        case -1:
            /*
             * Overflow of code_gen_buffer, or the current slice of it.
             *
             * TODO: We don't need to re-do gen_intermediate_code, nor
             * should we re-do the tcg optimization currently hidden
             * inside tcg_gen_code.  All that should be required is to
             * flush the TBs, allocate a new TB, re-initialize it per
             * above, and re-do the actual code generation.
             */
            goto buffer_overflow;

        case -2:
            /*
             * The code generated for the TranslationBlock is too large.
             * The maximum size allowed by the unwind info is 64k.
             * There may be stricter constraints from relocations
             * in the tcg backend.
             *
             * Try again with half as many insns as we attempted this time.
             * If a single insn overflows, there's a bug somewhere...
             */
            max_insns = tb->icount;
            assert(max_insns > 1);
            max_insns /= 2;
            goto tb_overflow;

        default:
            g_assert_not_reached();
        }
    }
    search_size = encode_search(tb, (void *)gen_code_buf + gen_code_size);
    if (unlikely(search_size < 0)) {
+2 −13
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ void translator_loop_temp_check(DisasContextBase *db)
}

void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
                     CPUState *cpu, TranslationBlock *tb)
                     CPUState *cpu, TranslationBlock *tb, int max_insns)
{
    int bp_insn = 0;

@@ -42,20 +42,9 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
    db->pc_next = db->pc_first;
    db->is_jmp = DISAS_NEXT;
    db->num_insns = 0;
    db->max_insns = max_insns;
    db->singlestep_enabled = cpu->singlestep_enabled;

    /* Instruction counting */
    db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
    if (db->max_insns == 0) {
        db->max_insns = CF_COUNT_MASK;
    }
    if (db->max_insns > TCG_MAX_INSNS) {
        db->max_insns = TCG_MAX_INSNS;
    }
    if (db->singlestep_enabled || singlestep) {
        db->max_insns = 1;
    }

    ops->init_disas_context(db, cpu);
    tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */

+2 −2
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ typedef ram_addr_t tb_page_addr_t;

#include "qemu/log.h"

void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb);
void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns);
void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
                          target_ulong *data);

void cpu_gen_init(void);
+2 −1
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ typedef struct TranslatorOps {
 * @db: Disassembly context.
 * @cpu: Target vCPU.
 * @tb: Translation block.
 * @max_insns: Maximum number of insns to translate.
 *
 * Generic translator loop.
 *
@@ -137,7 +138,7 @@ typedef struct TranslatorOps {
 * - When too many instructions have been translated.
 */
void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
                     CPUState *cpu, TranslationBlock *tb);
                     CPUState *cpu, TranslationBlock *tb, int max_insns);

void translator_loop_temp_check(DisasContextBase *db);

Loading