qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] cpu_regs in target-i386
@ 2011-11-27 13:46 Xin Tong
  2011-11-27 14:12 ` Andreas Färber
  0 siblings, 1 reply; 13+ messages in thread
From: Xin Tong @ 2011-11-27 13:46 UTC (permalink / raw)
  To: qemu-devel

When the x86 vcpu is initialized, a CPUX86State is qemu_mallocz'ed.
env is used to point to it and modifications to the CPUX86State can
thereby be done via the register that contains the env. I do not get
what the cpu_regs[CPU_NB_REGS] are for, do not we already have a set
of emulated x86 registers when we allocate the CPUX86State ?

Thanks

Xin

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 13:46 [Qemu-devel] cpu_regs in target-i386 Xin Tong
@ 2011-11-27 14:12 ` Andreas Färber
  2011-11-27 14:36   ` Xin Tong
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Färber @ 2011-11-27 14:12 UTC (permalink / raw)
  To: Xin Tong; +Cc: qemu-devel

Am 27.11.2011 14:46, schrieb Xin Tong:
> When the x86 vcpu is initialized, a CPUX86State is qemu_mallocz'ed.
> env is used to point to it and modifications to the CPUX86State can
> thereby be done via the register that contains the env. I do not get
> what the cpu_regs[CPU_NB_REGS] are for, do not we already have a set
> of emulated x86 registers when we allocate the CPUX86State ?

I assume in i386, too, it will be a TCGv array and will be initialized
to point to individual memory offsets inside CPU*State.
So they're for convenience and readability.

HTE,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 14:12 ` Andreas Färber
@ 2011-11-27 14:36   ` Xin Tong
  2011-11-27 14:53     ` Andreas Färber
  0 siblings, 1 reply; 13+ messages in thread
From: Xin Tong @ 2011-11-27 14:36 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

If i understand correctly here, those are just array of offsets for
the emulated registers such that the tcg can easily get access to the
address of the emulated registers. This is, however, different from
the env (CPUx86State) variable which will always have a host register
pointing to it ( host register is made to point to env in the tb enter
prologue).

Thanks

Xin


On Sun, Nov 27, 2011 at 9:12 AM, Andreas Färber <afaerber@suse.de> wrote:
> Am 27.11.2011 14:46, schrieb Xin Tong:
>> When the x86 vcpu is initialized, a CPUX86State is qemu_mallocz'ed.
>> env is used to point to it and modifications to the CPUX86State can
>> thereby be done via the register that contains the env. I do not get
>> what the cpu_regs[CPU_NB_REGS] are for, do not we already have a set
>> of emulated x86 registers when we allocate the CPUX86State ?
>
> I assume in i386, too, it will be a TCGv array and will be initialized
> to point to individual memory offsets inside CPU*State.
> So they're for convenience and readability.
>
> HTE,
> Andreas
>
> --
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 14:36   ` Xin Tong
@ 2011-11-27 14:53     ` Andreas Färber
  2011-11-27 15:23       ` Xin Tong
  0 siblings, 1 reply; 13+ messages in thread
From: Andreas Färber @ 2011-11-27 14:53 UTC (permalink / raw)
  To: Xin Tong; +Cc: qemu-devel

Am 27.11.2011 15:36, schrieb Xin Tong:
> If i understand correctly here, those are just array of offsets for
> the emulated registers such that the tcg can easily get access to the
> address of the emulated registers. This is, however, different from
> the env (CPUx86State) variable which will always have a host register
> pointing to it ( host register is made to point to env in the tb enter
> prologue).

Yes:

host register pointed to by cpu_env contains address of env
+
offset stored in cpu_* variable
=
address of corresponding struct member in env

Andreas

> On Sun, Nov 27, 2011 at 9:12 AM, Andreas Färber <afaerber@suse.de> wrote:
>> Am 27.11.2011 14:46, schrieb Xin Tong:
>>> When the x86 vcpu is initialized, a CPUX86State is qemu_mallocz'ed.
>>> env is used to point to it and modifications to the CPUX86State can
>>> thereby be done via the register that contains the env. I do not get
>>> what the cpu_regs[CPU_NB_REGS] are for, do not we already have a set
>>> of emulated x86 registers when we allocate the CPUX86State ?
>>
>> I assume in i386, too, it will be a TCGv array and will be initialized
>> to point to individual memory offsets inside CPU*State.
>> So they're for convenience and readability.
>>
>> HTE,
>> Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 14:53     ` Andreas Färber
@ 2011-11-27 15:23       ` Xin Tong
  2011-11-27 15:43         ` Peter Maydell
  2011-11-27 16:10         ` Andreas Färber
  0 siblings, 2 replies; 13+ messages in thread
From: Xin Tong @ 2011-11-27 15:23 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

This is a bit confusing then

in target-i386/translate.c

void optimize_flags_init(void)
{
  ...
  cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
                                          offsetof(CPUState, regs[15]), "r15");
  printf("offsetof(CPUState, regs[15]) is %ld\n", offsetof(CPUState, regs[15]));

  ...
}

output is cpu_regs[15] is 20, offsetof(CPUState, regs[15]) is 120,
should not cpu_regs[15] == 120 ?


Thanks

Xin






On Sun, Nov 27, 2011 at 9:53 AM, Andreas Färber <afaerber@suse.de> wrote:
> Am 27.11.2011 15:36, schrieb Xin Tong:
>> If i understand correctly here, those are just array of offsets for
>> the emulated registers such that the tcg can easily get access to the
>> address of the emulated registers. This is, however, different from
>> the env (CPUx86State) variable which will always have a host register
>> pointing to it ( host register is made to point to env in the tb enter
>> prologue).
>
> Yes:
>
> host register pointed to by cpu_env contains address of env
> +
> offset stored in cpu_* variable
> =
> address of corresponding struct member in env
>
> Andreas
>
>> On Sun, Nov 27, 2011 at 9:12 AM, Andreas Färber <afaerber@suse.de> wrote:
>>> Am 27.11.2011 14:46, schrieb Xin Tong:
>>>> When the x86 vcpu is initialized, a CPUX86State is qemu_mallocz'ed.
>>>> env is used to point to it and modifications to the CPUX86State can
>>>> thereby be done via the register that contains the env. I do not get
>>>> what the cpu_regs[CPU_NB_REGS] are for, do not we already have a set
>>>> of emulated x86 registers when we allocate the CPUX86State ?
>>>
>>> I assume in i386, too, it will be a TCGv array and will be initialized
>>> to point to individual memory offsets inside CPU*State.
>>> So they're for convenience and readability.
>>>
>>> HTE,
>>> Andreas
>
> --
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 15:23       ` Xin Tong
@ 2011-11-27 15:43         ` Peter Maydell
  2011-11-27 16:17           ` Xin Tong
  2011-11-27 16:10         ` Andreas Färber
  1 sibling, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2011-11-27 15:43 UTC (permalink / raw)
  To: Xin Tong; +Cc: Andreas Färber, qemu-devel

On 27 November 2011 15:23, Xin Tong <xerox.time.tech@gmail.com> wrote:
>  cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
>                                          offsetof(CPUState, regs[15]), "r15");
>  printf("offsetof(CPUState, regs[15]) is %ld\n", offsetof(CPUState, regs[15]));

> output is cpu_regs[15] is 20, offsetof(CPUState, regs[15]) is 120,
> should not cpu_regs[15] == 120 ?

No. tcg_global_mem_new_i64() returns a TCGv, which is (as far as
code in translate.c is concerned) an opaque reference which can
be passed to other TCG functions to cause code to be emitted
which uses that value (eg "add this value to something else").
So conceptually it represents "the value at the memory location
at (TCG_AREG0 + some offset)". If you then use this TCGv in a
tcg_gen_add_i64() we will generate code to load the value from
memory and add it. (TCG values can also be "the value stored in
this fixed native register" (used basically only for the cpu_env
pointer itself) or "a temporary value which TCG is free to allocate
to a register as it likes" (the most common).)

[The implementation is that it is an index into an array of
all the TCGv values TCG knows about, which is why it's a small
integer.]

-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 15:23       ` Xin Tong
  2011-11-27 15:43         ` Peter Maydell
@ 2011-11-27 16:10         ` Andreas Färber
  1 sibling, 0 replies; 13+ messages in thread
From: Andreas Färber @ 2011-11-27 16:10 UTC (permalink / raw)
  To: Xin Tong; +Cc: qemu-devel

Am 27.11.2011 16:23, schrieb Xin Tong:
> This is a bit confusing then
> 
> in target-i386/translate.c
> 
> void optimize_flags_init(void)
> {
>   ...
>   cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
>                                           offsetof(CPUState, regs[15]), "r15");
>   printf("offsetof(CPUState, regs[15]) is %ld\n", offsetof(CPUState, regs[15]));
> 
>   ...
> }
> 
> output is cpu_regs[15] is 20, offsetof(CPUState, regs[15]) is 120,
> should not cpu_regs[15] == 120 ?

Please don't top-post, your reply is out of context then. See below.

> On Sun, Nov 27, 2011 at 9:53 AM, Andreas Färber <afaerber@suse.de> wrote:
>> Am 27.11.2011 15:36, schrieb Xin Tong:
>>> If i understand correctly here, those are just array of offsets for
>>> the emulated registers such that the tcg can easily get access to the
>>> address of the emulated registers. This is, however, different from
>>> the env (CPUx86State) variable which will always have a host register
>>> pointing to it ( host register is made to point to env in the tb enter
>>> prologue).
>>
>> Yes:
>>
>> host register pointed to by cpu_env contains address of env
>> +
>> offset stored in cpu_* variable

Note that "variable" refers to TCG variable (TCGv), not C variable, cf.
tcg/README. If you do printf("%d", cpu_xyz), you will only see the
internal ID of that variable that points to data stored elsewhere. In
this case the ID happens to be constant because these are set up once
during target initialization.

>> =
>> address of corresponding struct member in env

When playing with TCG, configure with --enable-debug-tcg, then the
definitions are changed so that the compiler can make you aware of such
mixups.

Andreas

>>> On Sun, Nov 27, 2011 at 9:12 AM, Andreas Färber <afaerber@suse.de> wrote:
>>>> Am 27.11.2011 14:46, schrieb Xin Tong:
>>>>> When the x86 vcpu is initialized, a CPUX86State is qemu_mallocz'ed.
>>>>> env is used to point to it and modifications to the CPUX86State can
>>>>> thereby be done via the register that contains the env. I do not get
>>>>> what the cpu_regs[CPU_NB_REGS] are for, do not we already have a set
>>>>> of emulated x86 registers when we allocate the CPUX86State ?
>>>>
>>>> I assume in i386, too, it will be a TCGv array and will be initialized
>>>> to point to individual memory offsets inside CPU*State.
>>>> So they're for convenience and readability.


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 15:43         ` Peter Maydell
@ 2011-11-27 16:17           ` Xin Tong
  2011-11-27 20:59             ` Peter Maydell
  0 siblings, 1 reply; 13+ messages in thread
From: Xin Tong @ 2011-11-27 16:17 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Andreas Färber, qemu-devel

So the offset value (120) is really encapsulated in the TCGv
structure. and when we need the offset, we just call GET_TCGV_IA64
like what it is doing here

 static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
                                   TCGv_i64 arg3)
{
    *gen_opc_ptr++ = opc;
    *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
    *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
    *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
}


Thanks

Xin


On Sun, Nov 27, 2011 at 10:43 AM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> On 27 November 2011 15:23, Xin Tong <xerox.time.tech@gmail.com> wrote:
>>  cpu_regs[15] = tcg_global_mem_new_i64(TCG_AREG0,
>>                                          offsetof(CPUState, regs[15]), "r15");
>>  printf("offsetof(CPUState, regs[15]) is %ld\n", offsetof(CPUState, regs[15]));
>
>> output is cpu_regs[15] is 20, offsetof(CPUState, regs[15]) is 120,
>> should not cpu_regs[15] == 120 ?
>
> No. tcg_global_mem_new_i64() returns a TCGv, which is (as far as
> code in translate.c is concerned) an opaque reference which can
> be passed to other TCG functions to cause code to be emitted
> which uses that value (eg "add this value to something else").
> So conceptually it represents "the value at the memory location
> at (TCG_AREG0 + some offset)". If you then use this TCGv in a
> tcg_gen_add_i64() we will generate code to load the value from
> memory and add it. (TCG values can also be "the value stored in
> this fixed native register" (used basically only for the cpu_env
> pointer itself) or "a temporary value which TCG is free to allocate
> to a register as it likes" (the most common).)
>
> [The implementation is that it is an index into an array of
> all the TCGv values TCG knows about, which is why it's a small
> integer.]
>
> -- PMM
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 16:17           ` Xin Tong
@ 2011-11-27 20:59             ` Peter Maydell
  2011-11-27 23:07               ` Xin Tong
  0 siblings, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2011-11-27 20:59 UTC (permalink / raw)
  To: Xin Tong; +Cc: Andreas Färber, qemu-devel

On 27 November 2011 16:17, Xin Tong <xerox.time.tech@gmail.com> wrote:
> So the offset value (120) is really encapsulated in the TCGv
> structure. and when we need the offset, we just call GET_TCGV_IA64
> like what it is doing here
>
>  static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
>                                   TCGv_i64 arg3)
> {
>    *gen_opc_ptr++ = opc;
>    *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
>    *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
>    *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
> }

No, this is simply coping the TCGv from one place to another.
(GET_TCGV_I64() is a only a macro which checks at compile time
that you've really passed it a TCGv_i64 and not, say, a TCGv_i32.
In a non-debug build it does nothing.)

This function is writing out the intermediate representation
[see tcg/README] for a three-operand operation. We won't attempt
to actually use the offset value (120) until much later when a
subsequent pass reads the intermediate representation and writes
out native code for it.

-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 20:59             ` Peter Maydell
@ 2011-11-27 23:07               ` Xin Tong
  2011-11-27 23:33                 ` Peter Maydell
  0 siblings, 1 reply; 13+ messages in thread
From: Xin Tong @ 2011-11-27 23:07 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Andreas Färber, qemu-devel

can you please show me where the (120) is used. we pushed a global
TCGV to the gen_opparam_ptr. lets say the backend is i386 and the
operation is an add.

Thanks

Xin


On Sun, Nov 27, 2011 at 3:59 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 27 November 2011 16:17, Xin Tong <xerox.time.tech@gmail.com> wrote:
>> So the offset value (120) is really encapsulated in the TCGv
>> structure. and when we need the offset, we just call GET_TCGV_IA64
>> like what it is doing here
>>
>>  static inline void tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 arg1, TCGv_i64 arg2,
>>                                   TCGv_i64 arg3)
>> {
>>    *gen_opc_ptr++ = opc;
>>    *gen_opparam_ptr++ = GET_TCGV_I64(arg1);
>>    *gen_opparam_ptr++ = GET_TCGV_I64(arg2);
>>    *gen_opparam_ptr++ = GET_TCGV_I64(arg3);
>> }
>
> No, this is simply coping the TCGv from one place to another.
> (GET_TCGV_I64() is a only a macro which checks at compile time
> that you've really passed it a TCGv_i64 and not, say, a TCGv_i32.
> In a non-debug build it does nothing.)
>
> This function is writing out the intermediate representation
> [see tcg/README] for a three-operand operation. We won't attempt
> to actually use the offset value (120) until much later when a
> subsequent pass reads the intermediate representation and writes
> out native code for it.
>
> -- PMM
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 23:07               ` Xin Tong
@ 2011-11-27 23:33                 ` Peter Maydell
  2011-11-28  0:32                   ` Xin Tong
  0 siblings, 1 reply; 13+ messages in thread
From: Peter Maydell @ 2011-11-27 23:33 UTC (permalink / raw)
  To: Xin Tong; +Cc: Andreas Färber, qemu-devel

On 27 November 2011 23:07, Xin Tong <xerox.time.tech@gmail.com> wrote:
> can you please show me where the (120) is used. we pushed a global
> TCGV to the gen_opparam_ptr. lets say the backend is i386 and the
> operation is an add.

So, you can find it like this:

(1) starting from tcg_global_mem_new_i64 we follow where that
offset went, and we see that tcg_global_mem_new_internal stores
it in the mem_offset field of a TCGTemp structure.
(2) So we grep for uses of mem_offset, and we find that tcg.c
uses it in the register allocator; basically there are a lot
of places where we say "if this is a TEMP_VAL_MEM then either
load or store the value". We do that load or store by calling
tcg_out_ld() or tcg_out_st(), passing the mem_offset value
(plus some other stuff like the base register and whatever
temporary register the allocator wants to use for it).
(3) grepping for tcg_out_ld() we find it's implemented in the
backends. Specifically, tcg/i386/tcg-target.c has the x86
version which writes out x86 code to do a load/store from
[reg+offset].

So we can deduce that TCG doesn't try to be particularly
clever about these values -- we just load them when we need
them and store them again when they are updated. (We don't
try to support issuing add instructions with memory operands
even if the host CPU architecture has them.)

I didn't particularly know this in advance -- I'm just looking
through the code and searching for uses of things and implementations
of functions. QEMU's code generation is not particularly
exotic:
 * guest-specific front end decodes instructions and writes
   intermediate representation
 * optimisation pass that works on IR
 * liveness analysis (ie work out when data values are no
   longer needed, so we can reuse the registers they're in)
 * turn IR into generated code by making calls to a handful
   of host-specific backend functions

(about the only slightly unexpected thing is that we do the
register allocation as we go along generating the final
code, rather than doing it as a separate pass.)
So if you can get a grasp of the general structure then
following through it to answer specific questions like this
should be straightforward.

-- PMM

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-27 23:33                 ` Peter Maydell
@ 2011-11-28  0:32                   ` Xin Tong
  2011-11-28  1:00                     ` Xin Tong
  0 siblings, 1 reply; 13+ messages in thread
From: Xin Tong @ 2011-11-28  0:32 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Andreas Färber, qemu-devel

Thank you very much. This is very helpful.

Xin


On Sun, Nov 27, 2011 at 6:33 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 27 November 2011 23:07, Xin Tong <xerox.time.tech@gmail.com> wrote:
>> can you please show me where the (120) is used. we pushed a global
>> TCGV to the gen_opparam_ptr. lets say the backend is i386 and the
>> operation is an add.
>
> So, you can find it like this:
>
> (1) starting from tcg_global_mem_new_i64 we follow where that
> offset went, and we see that tcg_global_mem_new_internal stores
> it in the mem_offset field of a TCGTemp structure.
> (2) So we grep for uses of mem_offset, and we find that tcg.c
> uses it in the register allocator; basically there are a lot
> of places where we say "if this is a TEMP_VAL_MEM then either
> load or store the value". We do that load or store by calling
> tcg_out_ld() or tcg_out_st(), passing the mem_offset value
> (plus some other stuff like the base register and whatever
> temporary register the allocator wants to use for it).
> (3) grepping for tcg_out_ld() we find it's implemented in the
> backends. Specifically, tcg/i386/tcg-target.c has the x86
> version which writes out x86 code to do a load/store from
> [reg+offset].
>
> So we can deduce that TCG doesn't try to be particularly
> clever about these values -- we just load them when we need
> them and store them again when they are updated. (We don't
> try to support issuing add instructions with memory operands
> even if the host CPU architecture has them.)
>
> I didn't particularly know this in advance -- I'm just looking
> through the code and searching for uses of things and implementations
> of functions. QEMU's code generation is not particularly
> exotic:
>  * guest-specific front end decodes instructions and writes
>   intermediate representation
>  * optimisation pass that works on IR
>  * liveness analysis (ie work out when data values are no
>   longer needed, so we can reuse the registers they're in)
>  * turn IR into generated code by making calls to a handful
>   of host-specific backend functions
>
> (about the only slightly unexpected thing is that we do the
> register allocation as we go along generating the final
> code, rather than doing it as a separate pass.)
> So if you can get a grasp of the general structure then
> following through it to answer specific questions like this
> should be straightforward.
>
> -- PMM
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] cpu_regs in target-i386
  2011-11-28  0:32                   ` Xin Tong
@ 2011-11-28  1:00                     ` Xin Tong
  0 siblings, 0 replies; 13+ messages in thread
From: Xin Tong @ 2011-11-28  1:00 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Andreas Färber, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 4142 bytes --]

one more question. I was going through this code here. the lines in bold
are what happened when the second operand of the operation is a memory
location. what is the IS_DEAD_ARG(1), is the register allocator doing some
liveness analysis here ?


static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
                             const TCGArg *args,
                             unsigned int dead_args)
{
   TCGTemp *ts, *ots;
   int reg;
   const TCGArgConstraint *arg_ct;

   ots = &s->temps[args[0]];
   ts = &s->temps[args[1]];
   arg_ct = &def->args_ct[0];

   /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
   if (ts->val_type == TEMP_VAL_REG) {
       if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
           /* the mov can be suppressed */
           if (ots->val_type == TEMP_VAL_REG)
               s->reg_to_temp[ots->reg] = -1;
           reg = ts->reg;
           s->reg_to_temp[reg] = -1;
           ts->val_type = TEMP_VAL_DEAD;
       } else {
           if (ots->val_type == TEMP_VAL_REG) {
               reg = ots->reg;
           } else {
               reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
           }
           if (ts->reg != reg) {
               tcg_out_mov(s, ots->type, reg, ts->reg);
           }
       }
*   } else if (ts->val_type == TEMP_VAL_MEM) {
       if (ots->val_type == TEMP_VAL_REG) {
           reg = ots->reg;
       } else {
           reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
       }
       tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); *

      ...
}

Thanks

Xin



On Sun, Nov 27, 2011 at 7:32 PM, Xin Tong <xerox.time.tech@gmail.com> wrote:
> Thank you very much. This is very helpful.
>
> Xin
>
>
> On Sun, Nov 27, 2011 at 6:33 PM, Peter Maydell <peter.maydell@linaro.org>
wrote:
>> On 27 November 2011 23:07, Xin Tong <xerox.time.tech@gmail.com> wrote:
>>> can you please show me where the (120) is used. we pushed a global
>>> TCGV to the gen_opparam_ptr. lets say the backend is i386 and the
>>> operation is an add.
>>
>> So, you can find it like this:
>>
>> (1) starting from tcg_global_mem_new_i64 we follow where that
>> offset went, and we see that tcg_global_mem_new_internal stores
>> it in the mem_offset field of a TCGTemp structure.
>> (2) So we grep for uses of mem_offset, and we find that tcg.c
>> uses it in the register allocator; basically there are a lot
>> of places where we say "if this is a TEMP_VAL_MEM then either
>> load or store the value". We do that load or store by calling
>> tcg_out_ld() or tcg_out_st(), passing the mem_offset value
>> (plus some other stuff like the base register and whatever
>> temporary register the allocator wants to use for it).
>> (3) grepping for tcg_out_ld() we find it's implemented in the
>> backends. Specifically, tcg/i386/tcg-target.c has the x86
>> version which writes out x86 code to do a load/store from
>> [reg+offset].
>>
>> So we can deduce that TCG doesn't try to be particularly
>> clever about these values -- we just load them when we need
>> them and store them again when they are updated. (We don't
>> try to support issuing add instructions with memory operands
>> even if the host CPU architecture has them.)
>>
>> I didn't particularly know this in advance -- I'm just looking
>> through the code and searching for uses of things and implementations
>> of functions. QEMU's code generation is not particularly
>> exotic:
>>  * guest-specific front end decodes instructions and writes
>>   intermediate representation
>>  * optimisation pass that works on IR
>>  * liveness analysis (ie work out when data values are no
>>   longer needed, so we can reuse the registers they're in)
>>  * turn IR into generated code by making calls to a handful
>>   of host-specific backend functions
>>
>> (about the only slightly unexpected thing is that we do the
>> register allocation as we go along generating the final
>> code, rather than doing it as a separate pass.)
>> So if you can get a grasp of the general structure then
>> following through it to answer specific questions like this
>> should be straightforward.
>>
>> -- PMM
>>
>

[-- Attachment #2: Type: text/html, Size: 5183 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-11-28  1:00 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-27 13:46 [Qemu-devel] cpu_regs in target-i386 Xin Tong
2011-11-27 14:12 ` Andreas Färber
2011-11-27 14:36   ` Xin Tong
2011-11-27 14:53     ` Andreas Färber
2011-11-27 15:23       ` Xin Tong
2011-11-27 15:43         ` Peter Maydell
2011-11-27 16:17           ` Xin Tong
2011-11-27 20:59             ` Peter Maydell
2011-11-27 23:07               ` Xin Tong
2011-11-27 23:33                 ` Peter Maydell
2011-11-28  0:32                   ` Xin Tong
2011-11-28  1:00                     ` Xin Tong
2011-11-27 16:10         ` Andreas Färber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).