[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: |
Chen Gang S |
Subject: |
Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block. |
Date: |
Sun, 22 Feb 2015 08:25:06 +0800 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 |
On 2/22/15 00:33, Richard Henderson wrote:
> On 02/21/2015 07:31 AM, Chen Gang S wrote:
>>
>> - 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.
>
OK, thanks. For me, your idea is OK, it is more simpler (although with
more tcg temporary variables).
At present, the performance is not quite important, so I shall implement
the translation with the way which you provide below, thanks.
> For instance:
>
The demo code below is much valuable to me, but I guess, it can be
improved too (the related reply is below):
> 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;
It is branch_dest, not branch_desti.
> 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;
Do we need tcg_gen_exit_tb(0)? At present for simplify thinking, I always
use tcg_gen_exit_tb(0) for the end of one TB block.
> }
> }
>
> 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.
>
Excuse me, I am not quite familiar with tcg_gen_goto/exit_tb(), at
present, I still don't understand their parameters.
I guess, they are for performance (tb chaining), so I simply only use
tcg_gen_exit_tb(0), at present.
Welcome more information about tcg_gen_goto_tb() and tcg_gen_exit_tb().
> I hope this is enough to get started properly.
>
Yeah, it is really enough.
Thanks.
--
Chen Gang
Open, share, and attitude like air, water, and life which God blessed
- [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chen Gang S, 2015/02/20
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chen Gang S, 2015/02/21
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chen Gang S, 2015/02/21
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chen Gang S, 2015/02/21
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Richard Henderson, 2015/02/21
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block.,
Chen Gang S <=
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chris Metcalf, 2015/02/21
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chen Gang S, 2015/02/21
- Re: [Qemu-devel] [PATCH] target-tilegx: Finish decoding the first TB block., Chen Gang S, 2015/02/21