diff options
-rw-r--r-- | src/lj_emit_x86.h | 24 |
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 | { |