[Top][All Lists]

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

Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB blo

From: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block.
Date: Sat, 21 Feb 2015 08:33:22 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0

On 02/21/2015 07:31 AM, Chen Gang S wrote:
> Oh, we can not only assume y1 and x1 is the last execution in a bundle,
> e.g. in __libc_start_main:
>    11330:       c6f106c685928d8a        { addi r10, sp, 40 ; addi r13, sp, 32 
> ; st r25, r30 }
>    11338:       2862014010000fca        { moveli r10, 0 ; st r10, r0 }
> In this case, r10 will be over written. I have to use tcg temporary
> variables for it in each bundle:


>  - We can still use the original pipes order: "y0, y2, y1" and "x0, x1".

I guess, sure, though I don't think that'll help as much as you imagine.

>  - y0, y2, and x0 need to use tcg temporary variables, but y1 and x1 can
>    still use real variables.

Possibly, but I wouldn't structure it that way.  I'd have all of the pipes
write to temporaries.

>  - y1 and x1 need to flush the temporary variables, they also need to
>    consider about jump cases for tcg code (flush tcg temporary variables
>    after comparing and before jump).

I wouldn't do that either.  I'd have y1/x1 record that a branch occurred, and
the condition, but delay the flushing and branching to common code.

For instance:

typedef enum ExitStatus {
    NO_EXIT,         /* Fall through to next bundle */
    EXIT_JUMP,       /* Normal branch exit */
    EXIT_NORETURN    /* Exception taken (e.g. syscall) */
} ExitStatus;

typedef struct DisasContext {
    struct TranslationBlock *tb;
    int mem_idx;

    uint64_t pc;
    ExitStatus exit;

    int result_regs[3];
    TCGv result_vals[3];

    TCGCond branch_cond;
    TCGv branch_dest;
    TCGv branch_val1;
    TCGv branch_val2;
} DisasContext;

static void translate_one_bundle(DisasContext *dc, uint64_t bundle)
    int i;

    /* Initialize the per-bundle state of DC.  */
    dc->exit = NO_EXIT;
    for (i = 0; i < 3; ++i) {
        dc->result_regs[i] = -1;
    dc->branch_cond = TCG_COND_NEVER;
    dc->branch_desti = -1;

    /* Decode all pipes, writing results into DC.  */

    /* If some pipe raises an exception, nothing left to do.  */
    if (dc->exit == EXIT_NORETURN) {

    /* Write back register results from all pipes.  */
    for (i = 0; i < 3; ++i) {
        int r = dc->result_regs[i];
        if (r >= 0)
            tcg_gen_mov_i64(cpu_regs[r], dc->result_vals[i]);

    /* Write back branch results, i.e. take the branch now.  */
    if (dc->branch_cond != TCG_COND_NEVER) {
        if (dc->branch_cond == TCG_COND_ALWAYS) {
            /* Unconditional branch */
            tcg_gen_mov_i64(cpu_pc, dc->branch_dest);
        } else {
            /* Conditional branch */
            TCGv next_pc = tcg_const_i64(dc->pc + 8);
            tcg_gen_movcond_i64(dc->branch_cond, cpu_pc,
                                dc->branch_val1, dc->branch_val2,
                                dc->branch_dest, next_pc);
        dc->exit = EXIT_JUMP;

This mostly ignores the use of tcg_gen_goto_tb for now.  It's slightly more
complicated to use, and it makes debugging execution traces a bit harder.
Neither of which do you really want while bringing up the decoder.  However,
the eventual use of goto_tb is why we want to delay performing the branch until
after writing back the registers, rather than simply writing to cpu_pc right 

I hope this is enough to get started properly.


reply via email to

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