Message ID | 20090909120628.J4195@stanley.csl.cornell.edu |
---|---|
State | Superseded |
Headers | show |
On Wed, Sep 09, 2009 at 12:08:25PM -0400, Vince Weaver wrote: > > (re-sending) > > The extlh instruction on Alpha currently doesn't work properly. > It's a combination of a cut/paste bug (16 where it should be 32) as well > as a "shift by 64" bug. > > Below is a patch that fixes the problem. The previous e-mails on this > problem have test cases that exhibit the bug. > > This patch uses tcg_temp_local_new() at the suggestion of Filip Navara. > > Vince > > Signed-off-by: Vince Weaver <vince@csl.cornell.edu> > > diff --git a/target-alpha/translate.c b/target-alpha/translate.c > index 1fc5119..4219916 100644 > --- a/target-alpha/translate.c > +++ b/target-alpha/translate.c > @@ -526,14 +526,24 @@ static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1), > else > tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); > } else { > + int l1; > TCGv tmp1, tmp2; > - tmp1 = tcg_temp_new(); > + tmp1 = tcg_temp_local_new(); > + l1 = gen_new_label(); > + > tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7); > tcg_gen_shli_i64(tmp1, tmp1, 3); > + > + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); > + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp1, 0, l1); > + > tmp2 = tcg_const_i64(64); > tcg_gen_sub_i64(tmp1, tmp2, tmp1); > tcg_temp_free(tmp2); Given that a test costs a lot (partly due to the fact temp local variable must be used), I do wonder if doing a AND here wouldn't be better: tcg_gen_andi_i64(tmp1, tmp1, 0x3f); > tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1); > + > + gen_set_label(l1); > + > tcg_temp_free(tmp1); > } > if (tcg_gen_ext_i64) > @@ -1320,7 +1330,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) > break; > case 0x6A: > /* EXTLH */ > - gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); > + gen_ext_h(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit); > break; > case 0x72: > /* MSKQH */ > > >
On Wed, 16 Sep 2009, Aurelien Jarno wrote: > On Wed, Sep 09, 2009 at 12:08:25PM -0400, Vince Weaver wrote: > > } else { > > + int l1; > > TCGv tmp1, tmp2; > > - tmp1 = tcg_temp_new(); > > + tmp1 = tcg_temp_local_new(); > > + l1 = gen_new_label(); > > + > > tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7); > > tcg_gen_shli_i64(tmp1, tmp1, 3); > > + > > + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); > > + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp1, 0, l1); > > + > > tmp2 = tcg_const_i64(64); > > tcg_gen_sub_i64(tmp1, tmp2, tmp1); > > tcg_temp_free(tmp2); > > Given that a test costs a lot (partly due to the fact temp local > variable must be used), I do wonder if doing a AND here wouldn't > be better: > > tcg_gen_andi_i64(tmp1, tmp1, 0x3f); I'm not sure I follow. The code is attempting the following: tmp1=rb&0x7; tmp1=temp1<<3; if (tmp1!=0) { tmp1=64-tmp1; rc=ra<<tmp1; } else { rc=ra; } The problem with the original code is that in the case of tmp1 being 0, the shift left by 64 would result in 0, instead of the identity. I tried to avoid the jump but couldn't. Am I missing something? > > tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1); > > + > > + gen_set_label(l1); > > + Vince
On Wed, Sep 16, 2009 at 04:45:20PM -0400, Vince Weaver wrote: > On Wed, 16 Sep 2009, Aurelien Jarno wrote: > > > On Wed, Sep 09, 2009 at 12:08:25PM -0400, Vince Weaver wrote: > > > > } else { > > > + int l1; > > > TCGv tmp1, tmp2; > > > - tmp1 = tcg_temp_new(); > > > + tmp1 = tcg_temp_local_new(); > > > + l1 = gen_new_label(); > > > + > > > tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7); > > > tcg_gen_shli_i64(tmp1, tmp1, 3); > > > + > > > + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); > > > + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp1, 0, l1); > > > + > > > tmp2 = tcg_const_i64(64); > > > tcg_gen_sub_i64(tmp1, tmp2, tmp1); > > > tcg_temp_free(tmp2); > > > > Given that a test costs a lot (partly due to the fact temp local > > variable must be used), I do wonder if doing a AND here wouldn't > > be better: > > > > tcg_gen_andi_i64(tmp1, tmp1, 0x3f); > > I'm not sure I follow. > > The code is attempting the following: > > tmp1=rb&0x7; > tmp1=temp1<<3; > > if (tmp1!=0) { > tmp1=64-tmp1; > rc=ra<<tmp1; > } > else { > rc=ra; > } > > The problem with the original code is that in the case of tmp1 being 0, > the shift left by 64 would result in 0, instead of the identity. > > I tried to avoid the jump but couldn't. Am I missing something? > I mean the following code: tmp1=rb&0x7; tmp1=temp1<<3; tmp1=64-tmp1; tmp1=tmp1 & 0x3f; rc=ra<<tmp1; In case tmp1 = 0, it becomes 64, and then 0 again after the and, so rc=ra<<0.
Vince Weaver <vince@csl.cornell.edu> writes: > The code is attempting the following: > > tmp1=rb&0x7; > tmp1=temp1<<3; > > if (tmp1!=0) { > tmp1=64-tmp1; > rc=ra<<tmp1; > } > else { > rc=ra; > } > > The problem with the original code is that in the case of tmp1 being 0, > the shift left by 64 would result in 0, instead of the identity. > > I tried to avoid the jump but couldn't. Am I missing something? Instead of tmp1 = 64 - tmp1 use tmp1 = -tmp1 & 0x3f. Andreas.
diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 1fc5119..4219916 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -526,14 +526,24 @@ static always_inline void gen_ext_h(void (*tcg_gen_ext_i64)(TCGv t0, TCGv t1), else tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); } else { + int l1; TCGv tmp1, tmp2; - tmp1 = tcg_temp_new(); + tmp1 = tcg_temp_local_new(); + l1 = gen_new_label(); + tcg_gen_andi_i64(tmp1, cpu_ir[rb], 7); tcg_gen_shli_i64(tmp1, tmp1, 3); + + tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[ra]); + tcg_gen_brcondi_i64(TCG_COND_EQ, tmp1, 0, l1); + tmp2 = tcg_const_i64(64); tcg_gen_sub_i64(tmp1, tmp2, tmp1); tcg_temp_free(tmp2); tcg_gen_shl_i64(cpu_ir[rc], cpu_ir[ra], tmp1); + + gen_set_label(l1); + tcg_temp_free(tmp1); } if (tcg_gen_ext_i64) @@ -1320,7 +1330,7 @@ static always_inline int translate_one (DisasContext *ctx, uint32_t insn) break; case 0x6A: /* EXTLH */ - gen_ext_h(&tcg_gen_ext16u_i64, ra, rb, rc, islit, lit); + gen_ext_h(&tcg_gen_ext32u_i64, ra, rb, rc, islit, lit); break; case 0x72: /* MSKQH */
(re-sending) The extlh instruction on Alpha currently doesn't work properly. It's a combination of a cut/paste bug (16 where it should be 32) as well as a "shift by 64" bug. Below is a patch that fixes the problem. The previous e-mails on this problem have test cases that exhibit the bug. This patch uses tcg_temp_local_new() at the suggestion of Filip Navara. Vince Signed-off-by: Vince Weaver <vince@csl.cornell.edu>