aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_emit_x86.h24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/lj_emit_x86.h b/src/lj_emit_x86.h
index 5207f9da..5b139bd3 100644
--- a/src/lj_emit_x86.h
+++ b/src/lj_emit_x86.h
@@ -343,9 +343,27 @@ static void emit_rma(ASMState *as, x86Op xo, Reg rr, const void *addr)
343 emit_rmro(as, xo, rr, RID_DISPATCH, (int32_t)dispofs(as, addr)); 343 emit_rmro(as, xo, rr, RID_DISPATCH, (int32_t)dispofs(as, addr));
344 } else if (checki32(mcpofs(as, addr)) && checki32(mctopofs(as, addr))) { 344 } else if (checki32(mcpofs(as, addr)) && checki32(mctopofs(as, addr))) {
345 emit_rmro(as, xo, rr, RID_RIP, (int32_t)mcpofs(as, addr)); 345 emit_rmro(as, xo, rr, RID_RIP, (int32_t)mcpofs(as, addr));
346 } else if (!checki32((intptr_t)addr) && (xo == XO_MOV || xo == XO_MOVSD)) { 346 } else if (!checki32((intptr_t)addr)) {
347 emit_rmro(as, xo, rr, rr, 0); 347 Reg ra = (rr & 15);
348 emit_loadu64(as, rr, (uintptr_t)addr); 348 if (xo != XO_MOV) {
349 /* We can't allocate a register here. Use and restore DISPATCH. Ugly. */
350 uint64_t dispaddr = (uintptr_t)J2GG(as->J)->dispatch;
351 uint8_t i8 = xo == XO_GROUP3b ? *as->mcp++ : 0;
352 ra = RID_DISPATCH;
353 if (checku32(dispaddr)) {
354 emit_loadi(as, ra, (int32_t)dispaddr);
355 } else { /* Full-size 64 bit load. */
356 MCode *p = as->mcp;
357 *(uint64_t *)(p-8) = dispaddr;
358 p[-9] = (MCode)(XI_MOVri+(ra&7));
359 p[-10] = 0x48 + ((ra>>3)&1);
360 p -= 10;
361 as->mcp = p;
362 }
363 if (xo == XO_GROUP3b) emit_i8(as, i8);
364 }
365 emit_rmro(as, xo, rr, ra, 0);
366 emit_loadu64(as, ra, (uintptr_t)addr);
349 } else 367 } else
350#endif 368#endif
351 { 369 {