On 10/19/21 2:48 AM, Frédéric Pétrot wrote:
+static bool gen_setcond_i128(TCGv rl, TCGv rh, + TCGv al, TCGv ah, + TCGv bl, TCGv bh, + TCGCond cond) +{ + switch (cond) { + case TCG_COND_EQ: + tcg_gen_setcond_tl(TCG_COND_EQ, rl, al, bl); + tcg_gen_setcond_tl(TCG_COND_EQ, rh, ah, bh); + tcg_gen_and_tl(rl, rl, rh); + break; + + case TCG_COND_NE: + tcg_gen_setcond_tl(TCG_COND_NE, rl, al, bl); + tcg_gen_setcond_tl(TCG_COND_NE, rh, ah, bh); + tcg_gen_or_tl(rl, rl, rh); + break;
But of course setcond is more expensive than logic Better as xor + xor + or + setcond.
+ case TCG_COND_LTU: + { + TCGv tmp1 = tcg_temp_new(), + tmp2 = tcg_temp_new(); + + tcg_gen_sub2_tl(rl, rh, al, ah, bl, bh); + tcg_gen_eqv_tl(tmp1, ah, bh); + tcg_gen_and_tl(tmp1, tmp1, rh); + tcg_gen_andc_tl(tmp2, bh, ah); + tcg_gen_or_tl(tmp1, tmp1, tmp2); + tcg_gen_shri_tl(rl, tmp1, 63);
Hmm. Seems like it would work. I make that 7 operations. Or GEU in 6 operations: /* borrow in to second word */ setcond_tl(TCG_COND_LTU, t1, al, bl); /* seed third word with 1, which will be result */ sub2_tl(t1, t2, ah, one, t1, zero); sub2_tl(t1, rl, t1, t2, bh, zero);
+ } else { + gen_setcond_i128(tmpl, tmph, src1, src1h, src2, src2h, cond); + tcg_gen_brcondi_tl(TCG_COND_NE, tmpl, 0, l); + }
There are two setcond cases that invert their result; you should fold that in here and invert the branch condition. As long as you're special casing 0, you might as well special case TCG_COND_LT/GE and test the sign of the high word.
r~