All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: Chen Gang S <gang.chen@sunrus.com.cn>,
	Peter Maydell <peter.maydell@linaro.org>,
	Chris Metcalf <cmetcalf@ezchip.com>,
	Riku Voipio <riku.voipio@iki.fi>,
	"walt@tilera.com" <walt@tilera.com>
Cc: qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block.
Date: Sat, 21 Feb 2015 08:33:22 -0800	[thread overview]
Message-ID: <54E8B352.9040309@twiddle.net> (raw)
In-Reply-To: <54E8A4C9.3000101@sunrus.com.cn>

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:

Yes.

>  - 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;
        TCGV_UNUSED_I64(dc->result_vals[i]);
    }
    dc->branch_cond = TCG_COND_NEVER;
    dc->branch_desti = -1;
    TCGV_UNUSED_I64(dc->branch_dest);
    TCGV_UNUSED_I64(dc->branch_val1);
    TCGV_UNUSED_I64(dc->branch_val2);

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

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

    /* 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]);
            tcg_temp_free_i64(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);
            tcg_temp_free_i64(dc->branch_val1);
            tcg_temp_free_i64(dc->branch_val2);
            tcg_temp_free_i64(next_pc);
        }
        tcg_temp_free_i64(dc->branch_dest);
        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 away.

I hope this is enough to get started properly.


r~

  parent reply	other threads:[~2015-02-21 16:33 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-21  3:05 [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block Chen Gang S
2015-02-21  7:16 ` Chen Gang S
2015-02-21 15:31   ` Chen Gang S
2015-02-21 16:02     ` Chen Gang S
2015-02-21 16:33     ` Richard Henderson [this message]
2015-02-22  0:25       ` Chen Gang S
2015-02-22  0:25         ` Chris Metcalf
2015-02-22  1:08           ` Chen Gang S
2015-02-22  4:42             ` Chen Gang S

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=54E8B352.9040309@twiddle.net \
    --to=rth@twiddle.net \
    --cc=cmetcalf@ezchip.com \
    --cc=gang.chen@sunrus.com.cn \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    --cc=walt@tilera.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.