> -static inline void tcg_out_addi(TCGContext *s, int ext, > - TCGReg rd, TCGReg rn, unsigned int aimm) > +static void tcg_out_addi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, > + tcg_target_long aimm) > { > - /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */ > - /* using ADD 0x11000000 | (ext) | (aimm << 10) | (rn << 5) | rd */ > - unsigned int base = ext ? 0x91000000 : 0x11000000; > + enum aarch64_arith_opc opc = ARITH_ADDI; > + tcg_target_long lo, hi; > > - if (aimm <= 0xfff) { > - aimm <<= 10; > - } else { > - /* we can only shift left by 12, on assert we cannot represent */ > - assert(!(aimm & 0xfff)); > - assert(aimm <= 0xfff000); > - base |= 1 << 22; /* apply LSL 12 */ > - aimm >>= 2; > + if (aimm < 0) { > + aimm = -aimm; > + opc = ARITH_SUBI; > } > + hi = aimm & 0xfff000; > + lo = aimm & 0xfff; > + assert(aimm == hi + lo);
Won't this fail if aimm was -0x1000000 on entry? Jay.