Message ID | 1299087248-622-1-git-send-email-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
On Wed, Mar 02, 2011 at 05:34:08PM +0000, Peter Maydell wrote: > The code for Thumb2 ORNS (or negated and set flags) was trashing > a TCG input register which was needed later for use in calculating > flags, with the effect that the carry flag was always set with > the wrong sense. Fix this by using a TCG temporary instead. > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > --- > target-arm/translate.c | 11 +++++++++-- > 1 files changed, 9 insertions(+), 2 deletions(-) > > diff --git a/target-arm/translate.c b/target-arm/translate.c > index dbd958b..8f4e16b 100644 > --- a/target-arm/translate.c > +++ b/target-arm/translate.c > @@ -7326,10 +7326,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG > logic_cc = conds; > break; > case 3: /* orn */ > - tcg_gen_not_i32(t1, t1); > - tcg_gen_or_i32(t0, t0, t1); > + { > + /* We can't just invert t1 in place because we might need it > + * to calculate the carry flag later. > + */ > + TCGv tmp = tcg_temp_new_i32(); > + tcg_gen_not_i32(tmp, t1); > + tcg_gen_or_i32(t0, t0, tmp); > + tcg_temp_free_i32(tmp); You may want to use tcg_gen_orc_i32() instead, which as a bonus might be implemented directly on some hosts (currently ia64, powerpc and sparc). > logic_cc = conds; > break; > + } > case 4: /* eor */ > tcg_gen_xor_i32(t0, t0, t1); > logic_cc = conds; > -- > 1.7.1 > > >
diff --git a/target-arm/translate.c b/target-arm/translate.c index dbd958b..8f4e16b 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -7326,10 +7326,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG logic_cc = conds; break; case 3: /* orn */ - tcg_gen_not_i32(t1, t1); - tcg_gen_or_i32(t0, t0, t1); + { + /* We can't just invert t1 in place because we might need it + * to calculate the carry flag later. + */ + TCGv tmp = tcg_temp_new_i32(); + tcg_gen_not_i32(tmp, t1); + tcg_gen_or_i32(t0, t0, tmp); + tcg_temp_free_i32(tmp); logic_cc = conds; break; + } case 4: /* eor */ tcg_gen_xor_i32(t0, t0, t1); logic_cc = conds;
The code for Thumb2 ORNS (or negated and set flags) was trashing a TCG input register which was needed later for use in calculating flags, with the effect that the carry flag was always set with the wrong sense. Fix this by using a TCG temporary instead. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target-arm/translate.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)