diff --git a/src/lj_asm.c b/src/lj_asm.c index 9f33cfd9..367fe430 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -461,6 +461,14 @@ static void emit_jcc(ASMState *as, int cc, MCode *target) static void emit_call_(ASMState *as, MCode *target) { MCode *p = as->mcp; +#if LJ_64 + if (target-p != (int32_t)(target-p)) { + /* Assumes RID_RET is never an argument to calls and always clobbered. */ + emit_rr(as, XO_GROUP5, XOg_CALL, RID_RET); + emit_loadu64(as, RID_RET, (uint64_t)target); + return; + } +#endif *(int32_t *)(p-4) = jmprel(p, target); p[-5] = XI_CALL; as->mcp = p - 5; diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h index 65f829ac..ad4e3d1a 100644 --- a/src/lj_target_x86.h +++ b/src/lj_target_x86.h @@ -224,6 +224,8 @@ typedef enum { XO_TEST = XO_(85), XO_GROUP3b = XO_(f6), XO_GROUP3 = XO_(f7), + XO_GROUP5b = XO_(fe), + XO_GROUP5 = XO_(ff), XO_MOVZXb = XO_0f(b6), XO_MOVZXw = XO_0f(b7), XO_MOVSXb = XO_0f(be), @@ -278,6 +280,10 @@ typedef enum { XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV } x86Group3; +typedef enum { + XOg_INC, XOg_DEC, XOg_CALL, XOg_CALLfar, XOg_JMP, XOg_JMPfar, XOg_PUSH +} x86Group5; + /* x86 condition codes. */ typedef enum { CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,