On 9/20/21 1:04 AM, WANG Xuerui wrote:
+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
+ tcg_target_long val)
+{
+ tcg_target_long low, upper, higher, top;
+
+ if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
+ val = (int32_t)val;
+ }
+
+ /* Single-instruction cases. */
+ low = sextreg(val, 0, 12);
+ if (low == val) {
+ /* val fits in simm12: addi.w rd, zero, val */
+ tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
+ return;
+ }
+ if (0x800 <= val && val <= 0xfff) {
+ /* val fits in uimm12: ori rd, zero, val */
+ tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val);
+ return;
+ }
+
+ /* Chop upper bits into 3 immediate-field-sized segments respectively. */
+ upper = (val >> 12) & 0xfffff;
+ higher = (val >> 32) & 0xfffff;
+ top = val >> 52;
+
+ tcg_out_opc_lu12i_w(s, rd, upper);
+ if (low != 0) {
+ tcg_out_opc_ori(s, rd, rd, low);
+ }
+
+ if (sextreg(val, 0, 32) == val) {
+ /*
+ * Fits in 32-bits, upper bits are already properly sign-extended by
+ * lu12i.w.
+ */
+ return;
+ }
+ tcg_out_opc_cu32i_d(s, rd, higher);
+
+ if (sextreg(val, 0, 52) == val) {
+ /*
+ * Fits in 52-bits, upper bits are already properly sign-extended by
+ * cu32i.d.
+ */
+ return;
+ }
+ tcg_out_opc_cu52i_d(s, rd, rd, top);
Looks ok.
You'll want to check for small to medium pc-relative addresses. Almost every TB will load
the address of TB+C (0 <= C <= 3) at the end, and the TB structure immediately precedes
the code. Because of the odd values, you'll sometimes need two instructions. But that
will still be less than the 3-4 for a 52/64-bit address constant.
r~