+ unload_rs = OPT_EARLY_UNLOAD
+ && LIGHTREC_FLAGS_GET_RS(op->flags) == LIGHTREC_REG_UNLOAD;
+ discard_rs = OPT_EARLY_UNLOAD
+ && LIGHTREC_FLAGS_GET_RS(op->flags) == LIGHTREC_REG_DISCARD;
+
+ if ((unload_rs || discard_rs) && c.m.rs) {
+ /* If the source register is going to be unloaded or discarded,
+ * then we can simply mark its host register as now pointing to
+ * the destination register. */
+ pr_debug("Remap %s to %s at offset 0x%x\n",
+ lightrec_reg_name(c.m.rs), lightrec_reg_name(c.m.rd),
+ offset << 2);
+ rs = lightrec_alloc_reg_in(reg_cache, _jit, c.m.rs, 0);
+ lightrec_remap_reg(reg_cache, _jit, rs, c.m.rd, discard_rs);
+ lightrec_free_reg(reg_cache, rs);
+ return;
+ }
+
+ unload_rd = OPT_EARLY_UNLOAD
+ && LIGHTREC_FLAGS_GET_RD(op->flags) == LIGHTREC_REG_UNLOAD;
+
+ if (unload_rd) {
+ /* If the destination register will be unloaded right after the
+ * MOV meta-opcode, we don't actually need to write any host
+ * register - we can just store the source register directly to
+ * the register cache, at the offset corresponding to the
+ * destination register. */
+ lightrec_discard_reg_if_loaded(reg_cache, c.m.rd);
+
+ rs = lightrec_alloc_reg_in(reg_cache, _jit, c.m.rs, 0);
+
+ jit_stxi_i(lightrec_offset(regs.gpr) + (c.m.rd << 2), LIGHTREC_REG_STATE, rs);