+static void emit_movimm_from64(u_int rs_val, u_int rs, uintptr_t rt_val, u_int rt)
+{
+ if (rt_val < 0x100000000ull) {
+ emit_movimm_from(rs_val, rs, rt_val, rt);
+ return;
+ }
+ // just move the whole thing. At least on Linux all addresses
+ // seem to be 48bit, so 3 insns - not great not terrible
+ assem_debug("movz %s,#%#lx\n", regname64[rt], rt_val & 0xffff);
+ output_w32(0xd2800000 | imm16_rd(rt_val & 0xffff, rt));
+ assem_debug("movk %s,#%#lx,lsl #16\n", regname64[rt], (rt_val >> 16) & 0xffff);
+ output_w32(0xf2a00000 | imm16_rd((rt_val >> 16) & 0xffff, rt));
+ assem_debug("movk %s,#%#lx,lsl #32\n", regname64[rt], (rt_val >> 32) & 0xffff);
+ output_w32(0xf2c00000 | imm16_rd((rt_val >> 32) & 0xffff, rt));
+ if (rt_val >> 48) {
+ assem_debug("movk %s,#%#lx,lsl #48\n", regname64[rt], (rt_val >> 48) & 0xffff);
+ output_w32(0xf2e00000 | imm16_rd((rt_val >> 48) & 0xffff, rt));
+ }
+}
+
+// trashes x2