On 27.05.2013 20:47, Richard Henderson wrote: > On 2013-05-27 04:43, Claudio Fontana wrote: >>> Hmm, true. Although I'd been thinking more along the lines of >>> arranging the code such that we'd use movz to set the zero. >> >> I think we need to keep treating zero specially if we want to keep the >> optimization where we don't emit needless MOVK instructions for half-words >> of value 0000h. >> >> I can however make one single function out of movi32 and movi64, it could >> look like this: >> >> if (!value) { >> tcg_out_movr(s, 0, rd, TCG_REG_ZXR); >> return; >> } >> >> base = (value > 0xffffffff) ? 0xd2800000 : 0x52800000; >> >> while (value) { >> /* etc etc */ >> } > > > if (type == TCG_TYPE_I32) { > value = (uint32_t)value; > ext = 0; > } else if (value <= 0xffffffff) { > ext = 0; > } else { > ext = 0x80000000; > }
The check for type is probably unnecessary, since we don't gain anything (we still have to check something once), so I'd rather use a uint64_t parameter and then just check for value < 0xffffffff. > > base = 0x52800000; /* MOVZ */ > do { > int shift = ctz64(value) & (63 & -16); > int half = (value >> shift) & 0xffff; > tcg_out32(s, base | ext | half << 5 | rd); > value &= ~(0xffffUL << shift); > base = 0x72800000; /* MOVK */ > } while (value != 0); > > > Since we go through the loop at least once, we emit the movz for zero input. > No need for any extra tests. And using ctz we can iterate fewer times. Of course, doh. I'll make use of do..while. Thanks, Claudio