On 9/24/21 11:08 AM, WANG Xuerui wrote:
Oops, for some reason I only received this at about 8 pm...
That was my fault. I wrote a bunch of stuff off-line yesterday while
traveling, and the mail queue only flushed this morning.
I'll note there's a bug in my example code wrt initializing rd with
addi, then overwriting with cu32i.d.
I like your v4 version of movi, with the high-bit-set predicate. The
only case I can think of that you miss is e.g. 0x7fffffffffffffff,
which can be
addi.w rd, zero, -1
cu52i.d rd, rd, 0x7ff
One possibility is to extract a subroutine:
static void tcg_out_movi_i32(TCGContext *s, TCGReg rd, int32_t val)
{
/* Single instruction cases */
/* else lu12i.w + ori */
}
static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
tcg_target_long val)
{
if (type == TCG_TYPE_I32 || val == (int32_t)val) {
tcg_out_movi_i32(s, rd, val);
return;
}
/* PC-relative cases */
if (ctz64(val) >= 52) {
tcg_out_opc_cu52i_d(s, rd, TCG_REG_ZERO, val >> 52);
return;
}
/* Slow path. Initialize the low 32-bits, then concat high bits. */
tcg_out_movi_i32(s, rd, val);
rd_high_bits_are_ones = (int32_t)val < 0);
/* Your imm_part_needs_loading checks; rd is always written. */
}