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. */ } r~