qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 5/7] tcg-i386: Implement deposit operation.


From: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH 5/7] tcg-i386: Implement deposit operation.
Date: Wed, 26 Jan 2011 10:21:03 -0800
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Thunderbird/3.1.7

On 01/26/2011 08:50 AM, Alexander Graf wrote:
> Oh, you mean basically to have the following:
> 
> TCGv_i32 regs32[16];
> TCGv_i64 regs[16];
> 
> Then declare both as globals with offset and just switch between the
> access type using a disas struct variable. Once the TB ends, I'd
> obviously have to sync back to 64 bit again.

Maybe?  I don't think that regs32 can overlap with regs in the real
cpu structure.  Otherwise you have the same sort of sync problems as
was originally rejected.

I had been picturing regs32 as a member of DisasContext, and it would
hold tcg_temp_new_i32 variables as-needed.  Something like

#if TCG_TARGET_REG_BITS == 64

static void writeback_reg32(DisasContext *dc, int r)
{
    // ??? This macro should really exist to match TCGV_UNUSED_I32 etc.
    if (!TCGV_IS_UNUSED_I32 (dc->regs32[r])) {
        tcg_gen_deposit_tl(cpu_regs[r], cpu_regs[r],
                           MAKE_TCGV_I64 (GET_TCGV_I32 (dc->regs32[r])),
                           0, 32);
    }
}

static void writeback_all_reg32(DisasContext *dc)
{
    int i;
    for (i = 0; i < 16; ++i) {
        flush_reg32(dc, i);
    }
}

static void flush_all_reg32(DisasContext *dc)
{
    int i;
    for (i = 0; i < 16; ++i) {
        if (!TCGV_IS_UNUSED_I32 (dc->regs32[r])) {
            tcg_temp_free_i32 (dc->regs32[r]);
            TCGV_UNUSED_I32 (dc->regs32[r]);
        }
    }
}

static TCGv_i32 get_reg32(DisasContext *dc, int r)
{
    if (TCGV_IS_UNUSED_I32 (dc->regs32[r])) {
        dc->regs32[r] = tcg_temp_new_i32();
        tcg_gen_trunc_i64_i32(dc->regs32[r], cpu_regs[r]);
    }
    return dc->regs32[r];
}

static TCGv_i64 get_reg64(DisasContext *dc, int r)
{
    writeback_reg32(dc, r);
    return cpu_regs[r];
}

#elif TCG_TARGET_REG_BITS == 32

static void writeback_reg32(DisasContext *dc, int r) { }
static void writeback_all_reg32(DisasContext *dc) { }
static void flush_all_reg32(DisasContext *dc) { }

static TCGv_i32 get_reg32(DisasContext *dc, int r)
{
    return TCGV_LOW(cpu_regs[r]);
}

static TCGv_i64 get_reg64(DisasContext *dc, int r)
{
    return cpu_regs[r];
}

#endif


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]