[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v4] target-microblaze: lwx/swx: first implementa
From: |
Peter Crosthwaite |
Subject: |
Re: [Qemu-devel] [PATCH v4] target-microblaze: lwx/swx: first implementation |
Date: |
Tue, 5 Jun 2012 12:34:31 +1000 |
Thanks Stefan,
Fix is up on the mailing list. I went for the simple solution of just
always initing the tcg variables with tcg_temp_*new. May be a minor
performance penalty but noting noticeable.
Regards,
Peter
On Tue, Jun 5, 2012 at 6:26 AM, Stefan Weil <address@hidden> wrote:
> Hi Peter,
>
> this patch (which was applied to QEMU master) breaks debug builds
> (configure --enable-debug). see my comment below.
>
> Regards,
>
> Stefan W.
>
>
>
> Am 01.06.2012 05:23, schrieb Peter A. G. Crosthwaite:
>>
>> Signed-off-by: Peter A. G. Crosthwaite<address@hidden>
>>
>> ---
>> changed from v3:
>> simplified tcg local variable usage aqcross branch
>> changed from v2:
>> fixed tcg local variable usage across branch
>> reworked carry logic (with new write_carryi() function)
>> made LOG_DIS show lwx swx properly
>> changed from v1:
>> implemented reservation address checking
>> created new cpu state variable specifically for reservation address/flag
>> state
>>
>> target-microblaze/cpu.c | 1 +
>> target-microblaze/cpu.h | 4 ++
>> target-microblaze/helper.c | 2 +
>> target-microblaze/translate.c | 62
>> +++++++++++++++++++++++++++++++++++++---
>> 4 files changed, 64 insertions(+), 5 deletions(-)
>>
>
> ...
>
>> diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
>> index a362938..f0ebd59 100644
>> --- a/target-microblaze/translate.c
>> +++ b/target-microblaze/translate.c
>> @@ -162,6 +162,14 @@ static void write_carry(DisasContext *dc, TCGv v)
>> tcg_temp_free(t0);
>> }
>>
>> +static void write_carryi(DisasContext *dc, int carry)
>> +{
>> + TCGv t0 = tcg_temp_new();
>> + tcg_gen_movi_tl(t0, carry ? 1 : 0);
>> + write_carry(dc, t0);
>> + tcg_temp_free(t0);
>> +}
>> +
>> /* True if ALU operand b is a small immediate that may deserve
>> faster treatment. */
>> static inline int dec_alu_op_b_is_small_imm(DisasContext *dc)
>> @@ -948,12 +956,13 @@ static inline void dec_byteswap(DisasContext *dc,
>> TCGv dst, TCGv src, int size)
>> static void dec_load(DisasContext *dc)
>> {
>> TCGv t, *addr;
>> - unsigned int size, rev = 0;
>> + unsigned int size, rev = 0, ex = 0;
>>
>> size = 1<< (dc->opcode& 3);
>>
>> if (!dc->type_b) {
>> rev = (dc->ir>> 9)& 1;
>>
>> + ex = (dc->ir>> 10)& 1;
>> }
>>
>> if (size> 4&& (dc->tb_flags& MSR_EE_FLAG)
>>
>> @@ -963,7 +972,8 @@ static void dec_load(DisasContext *dc)
>> return;
>> }
>>
>> - LOG_DIS("l%d%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "");
>> + LOG_DIS("l%d%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
>> + ex ? "x" : "");
>>
>> t_sync_flags(dc);
>> addr = compute_ldst_addr(dc,&t);
>> @@ -1019,6 +1029,17 @@ static void dec_load(DisasContext *dc)
>> }
>> }
>>
>> + /* lwx does not throw unaligned access errors, so force alignment */
>> + if (ex) {
>> + /* Force addr into the temp. */
>> + if (addr !=&t) {
>> + t = tcg_temp_new();
>> + tcg_gen_mov_tl(t, *addr);
>> + addr =&t;
>> + }
>> + tcg_gen_andi_tl(t, t, ~3);
>> + }
>> +
>> /* If we get a fault on a dslot, the jmpstate better be in sync. */
>> sync_jmpstate(dc);
>>
>> @@ -1057,6 +1078,12 @@ static void dec_load(DisasContext *dc)
>> }
>> }
>>
>> + if (ex) { /* lwx */
>> + /* no support for for AXI exclusive so always clear C */
>> + write_carryi(dc, 0);
>> + tcg_gen_st_tl(*addr, cpu_env, offsetof(CPUMBState, res_addr));
>> + }
>> +
>> if (addr ==&t)
>> tcg_temp_free(t);
>> }
>> @@ -1078,12 +1105,14 @@ static void gen_store(DisasContext *dc, TCGv addr,
>> TCGv val,
>>
>> static void dec_store(DisasContext *dc)
>> {
>> - TCGv t, *addr;
>> - unsigned int size, rev = 0;
>> + TCGv t, *addr, swx_addr, r_check = 0;
>
>
> With --enable-debug, TCGv is a struct (not an int),
> therefore r_check = 0 does not work.
>
> swx_addr and r_check are used in the same context.
> Can their declarations be moved to the block where
> they are first used?
>
> If that is not possible, either none or both of these
> two variables should be initialised.
>
>
>> + int swx_skip = 0;
>> + unsigned int size, rev = 0, ex = 0;
>>
>> size = 1<< (dc->opcode& 3);
>> if (!dc->type_b) {
>> rev = (dc->ir>> 9)& 1;
>>
>> + ex = (dc->ir>> 10)& 1;
>> }
>>
>> if (size> 4&& (dc->tb_flags& MSR_EE_FLAG)
>>
>> @@ -1093,12 +1122,30 @@ static void dec_store(DisasContext *dc)
>> return;
>> }
>>
>> - LOG_DIS("s%d%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "");
>> + LOG_DIS("s%d%s%s%s\n", size, dc->type_b ? "i" : "", rev ? "r" : "",
>> + ex ? "x" : "");
>> t_sync_flags(dc);
>> /* If we get a fault on a dslot, the jmpstate better be in sync. */
>> sync_jmpstate(dc);
>> addr = compute_ldst_addr(dc,&t);
>>
>> + if (ex) { /* swx */
>> + r_check = tcg_temp_new();
>> + swx_addr = tcg_temp_local_new();
>
>
>
> TCGv r_check = ...;
> TCGv swx_addr = ...;
>
>
>> +
>> + /* Force addr into the swx_addr. */
>> + tcg_gen_mov_tl(swx_addr, *addr);
>> + addr =&swx_addr;
>> + /* swx does not throw unaligned access errors, so force alignment
>> */
>> + tcg_gen_andi_tl(swx_addr, swx_addr, ~3);
>> +
>> + tcg_gen_ld_tl(r_check, cpu_env, offsetof(CPUMBState, res_addr));
>> + write_carryi(dc, 1);
>> + swx_skip = gen_new_label();
>> + tcg_gen_brcond_tl(TCG_COND_NE, r_check, swx_addr, swx_skip);
>> + write_carryi(dc, 0);
>
>
> Add this code from block at end of function?
>
> gen_set_label(swx_skip);
> tcg_temp_free(swx_addr);
> tcg_temp_free(r_check);
>
>> + }
>> +
>> if (rev&& size != 4) {
>>
>> /* Endian reverse the address. t is addr. */
>> switch (size) {
>> @@ -1174,6 +1221,11 @@ static void dec_store(DisasContext *dc)
>> gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
>> tcg_const_tl(1), tcg_const_tl(size - 1));
>> }
>
>
> Move the following conditional block up?
>
>
>> + if (ex) {
>> + gen_set_label(swx_skip);
>> + tcg_temp_free(r_check);
>> + tcg_temp_free(swx_addr);
>> + }
>
>