> > +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?