> > +void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo,
> > +                 HexValue *dst, HexValue *val)
> > +{
> > +    yyassert(c, locp, hi->type == IMMEDIATE &&
> > +             hi->imm.type == VALUE &&
> > +             lo->type == IMMEDIATE &&
> > +             lo->imm.type == VALUE,
> > +             "Range deposit needs immediate values!\n");
> > +
> > +    *val = rvalue_truncate(c, locp, val);
> > +    unsigned len = hi->imm.value + 1 - lo->imm.value;
> > +    HexValue tmp = gen_tmp(c, locp, 32);
> > +    OUT(c, locp, "tcg_gen_neg_i32(", &tmp, ", ", val, ");\n");
> > +    OUT(c, locp, "tcg_gen_deposit_i32(", dst, ", ", dst, ", ", &tmp, ", ");
> > +    OUT(c, locp, lo, ", ", &len, ");\n");
>
>
> This doesn't match the C semantics of fSETBITS
>
> #define fSETBIT(N, DST, VAL) \
>     do { \
>         DST = (DST & ~(1ULL << (N))) | (((uint64_t)(VAL)) << (N)); \
>     } while (0)
>
> #define fGETBIT(N, SRC) (((SRC) >> N) & 1)
> #define fSETBITS(HI, LO, DST, VAL) \
>     do { \
>         int j; \
>         for (j = LO; j <= HI; j++) { \
>             fSETBIT(j, DST, VAL); \
>         } \
>     } while (0)
>
> You need to put len copies of LSB(val), so emit something like this
>     TCGv zero = tcg_const_tl(0);
>     TCGv ones = tcg_const_tl(~0);
>     tcg_gen_andi_tl(tmp, val, 1);
>     tcg_gen_movcond_tl(TCG_COND_NE, tmp, tmp, zero, ones, zero);
>     tcg_gen_deposit_tl(dst, dst, tmp, lo, len);
>     tcg_temp_free(zero);
>     tcg_temp_free(ones);

The change was suggested by (I think) Richard some patchset ago and I
think it is semantically equivalent.
I checked `compare.idef` and every value of `VAL` comes from a
comparison, which has value either `0` or `1`.
Applying `neg` turns it into either `0` or `0xFFFFFFFF`, making the
`deposit` work as intended.

Am I missing something?

Reply via email to