Browse Source

Generate indirect calls for out-of-range distances on x64.

Mike Pall 15 years ago
parent
commit
e807d46931
2 changed files with 14 additions and 0 deletions
  1. 8 0
      src/lj_asm.c
  2. 6 0
      src/lj_target_x86.h

+ 8 - 0
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)
 static void emit_call_(ASMState *as, MCode *target)
 {
 {
   MCode *p = as->mcp;
   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);
   *(int32_t *)(p-4) = jmprel(p, target);
   p[-5] = XI_CALL;
   p[-5] = XI_CALL;
   as->mcp = p - 5;
   as->mcp = p - 5;

+ 6 - 0
src/lj_target_x86.h

@@ -224,6 +224,8 @@ typedef enum {
   XO_TEST =	XO_(85),
   XO_TEST =	XO_(85),
   XO_GROUP3b =	XO_(f6),
   XO_GROUP3b =	XO_(f6),
   XO_GROUP3 =	XO_(f7),
   XO_GROUP3 =	XO_(f7),
+  XO_GROUP5b =	XO_(fe),
+  XO_GROUP5 =	XO_(ff),
   XO_MOVZXb =	XO_0f(b6),
   XO_MOVZXb =	XO_0f(b6),
   XO_MOVZXw =	XO_0f(b7),
   XO_MOVZXw =	XO_0f(b7),
   XO_MOVSXb =	XO_0f(be),
   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
   XOg_TEST, XOg_TEST_, XOg_NOT, XOg_NEG, XOg_MUL, XOg_IMUL, XOg_DIV, XOg_IDIV
 } x86Group3;
 } x86Group3;
 
 
+typedef enum {
+  XOg_INC, XOg_DEC, XOg_CALL, XOg_CALLfar, XOg_JMP, XOg_JMPfar, XOg_PUSH
+} x86Group5;
+
 /* x86 condition codes. */
 /* x86 condition codes. */
 typedef enum {
 typedef enum {
   CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,
   CC_O, CC_NO, CC_B, CC_NB, CC_E, CC_NE, CC_BE, CC_NBE,