Commit 279de61a authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Split gen_nop_hint



Now that all callers pass a constant value, split the switch
statement into the individual trans_* functions.

Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190904193059.26202-61-richard.henderson@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 56e6250e
Loading
Loading
Loading
Loading
+24 −43
Original line number Diff line number Diff line
@@ -3061,46 +3061,6 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
    gen_rfe(s, pc, load_cpu_field(spsr));
}

/*
 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
 * only call the helper when running single threaded TCG code to ensure
 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
 * just skip this instruction. Currently the SEV/SEVL instructions
 * which are *one* of many ways to wake the CPU from WFE are not
 * implemented so we can't sleep like WFI does.
 */
static void gen_nop_hint(DisasContext *s, int val)
{
    switch (val) {
        /* When running in MTTCG we don't generate jumps to the yield and
         * WFE helpers as it won't affect the scheduling of other vCPUs.
         * If we wanted to more completely model WFE/SEV so we don't busy
         * spin unnecessarily we would need to do something more involved.
         */
    case 1: /* yield */
        if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
            gen_set_pc_im(s, s->base.pc_next);
            s->base.is_jmp = DISAS_YIELD;
        }
        break;
    case 3: /* wfi */
        gen_set_pc_im(s, s->base.pc_next);
        s->base.is_jmp = DISAS_WFI;
        break;
    case 2: /* wfe */
        if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
            gen_set_pc_im(s, s->base.pc_next);
            s->base.is_jmp = DISAS_WFE;
        }
        break;
    case 4: /* sev */
    case 5: /* sevl */
        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
    default: /* nop */
        break;
    }
}

#define CPU_V001 cpu_V0, cpu_V0, cpu_V1

static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
@@ -8194,19 +8154,40 @@ DO_SMLAWX(SMLAWT, 1, 1)

static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
{
    gen_nop_hint(s, 1);
    /*
     * When running single-threaded TCG code, use the helper to ensure that
     * the next round-robin scheduled vCPU gets a crack.  When running in
     * MTTCG we don't generate jumps to the helper as it won't affect the
     * scheduling of other vCPUs.
     */
    if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
        gen_set_pc_im(s, s->base.pc_next);
        s->base.is_jmp = DISAS_YIELD;
    }
    return true;
}

static bool trans_WFE(DisasContext *s, arg_WFE *a)
{
    gen_nop_hint(s, 2);
    /*
     * When running single-threaded TCG code, use the helper to ensure that
     * the next round-robin scheduled vCPU gets a crack.  In MTTCG mode we
     * just skip this instruction.  Currently the SEV/SEVL instructions,
     * which are *one* of many ways to wake the CPU from WFE, are not
     * implemented so we can't sleep like WFI does.
     */
    if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
        gen_set_pc_im(s, s->base.pc_next);
        s->base.is_jmp = DISAS_WFE;
    }
    return true;
}

static bool trans_WFI(DisasContext *s, arg_WFI *a)
{
    gen_nop_hint(s, 3);
    /* For WFI, halt the vCPU until an IRQ. */
    gen_set_pc_im(s, s->base.pc_next);
    s->base.is_jmp = DISAS_WFI;
    return true;
}